|
From: <tho...@us...> - 2010-10-01 15:36:16
|
Revision: 3713
http://bigdata.svn.sourceforge.net/bigdata/?rev=3713&view=rev
Author: thompsonbry
Date: 2010-10-01 15:36:09 +0000 (Fri, 01 Oct 2010)
Log Message:
-----------
Added some interfaces for reporting on those aspects of a B+Tree which feed into cost estimates for query plans.
Integrated the named graph decision tree logic with the B+Tree cost model in QueryEngine. I've only done this for standalone as this point. We will have to override this for scale-out to use an approximation of the mixtures of cost models for a BTree on the Journal and ~3 index segment files. That can be overridden in FederatedQueryEngine.
Modified Paths:
--------------
branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpBase.java
branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ap/Predicate.java
branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/cost/BTreeCostModel.java
branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/cost/DiskCostModel.java
branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/cost/IndexSegmentCostModel.java
branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/QueryEngine.java
branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/Rule2BOpUtility.java
branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/fed/FederatedQueryEngine.java
branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/AbstractBTree.java
Added Paths:
-----------
branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/BTreeStatistics.java
branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/BTreeUtilizationReport.java
branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/IBTreeStatistics.java
branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/IBTreeUtilizationReport.java
Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpBase.java
===================================================================
--- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpBase.java 2010-10-01 15:14:05 UTC (rev 3712)
+++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpBase.java 2010-10-01 15:36:09 UTC (rev 3713)
@@ -453,15 +453,32 @@
sb.append(',');
sb.append(t.getClass().getSimpleName());
}
- sb.append(")[");
- final Integer id = (Integer) annotations.get(Annotations.BOP_ID);
- if (id != null)
- sb.append("Annotations.BOP_ID=" + id);
- sb.append("]");
+ sb.append(")");
+ annotationsToString(sb);
return sb.toString();
}
+ protected void annotationsToString(final StringBuilder sb) {
+ final Map<String,Object> annotations = annotations();
+ if (!annotations.isEmpty()) {
+ sb.append("[");
+ boolean first = true;
+ for (Map.Entry<String, Object> e : annotations.entrySet()) {
+ if (!first)
+ sb.append(", ");
+ if (e.getValue() != null && e.getValue().getClass().isArray()) {
+ sb.append(e.getKey() + "="
+ + Arrays.toString((Object[]) e.getValue()));
+ } else {
+ sb.append(e.getKey() + "=" + e.getValue());
+ }
+ first = false;
+ }
+ sb.append("]");
+ }
+ }
+
final public BOpEvaluationContext getEvaluationContext() {
return getProperty(Annotations.EVALUATION_CONTEXT,
Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ap/Predicate.java
===================================================================
--- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ap/Predicate.java 2010-10-01 15:14:05 UTC (rev 3712)
+++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ap/Predicate.java 2010-10-01 15:36:09 UTC (rev 3713)
@@ -31,8 +31,6 @@
import java.util.Iterator;
import java.util.Map;
-import cern.colt.Arrays;
-
import com.bigdata.bop.AbstractAccessPathOp;
import com.bigdata.bop.ArrayBindingSet;
import com.bigdata.bop.BOp;
@@ -44,8 +42,6 @@
import com.bigdata.bop.IVariable;
import com.bigdata.bop.IVariableOrConstant;
import com.bigdata.bop.NV;
-import com.bigdata.rdf.internal.IV;
-import com.bigdata.rdf.spo.SPOPredicate;
import com.bigdata.relation.accesspath.ElementFilter;
import com.bigdata.relation.accesspath.IElementFilter;
import com.bigdata.relation.rule.ISolutionExpander;
@@ -553,28 +549,7 @@
}
sb.append(")");
-
- final Map<String,Object> annotations = annotations();
- if (!annotations.isEmpty()) {
- sb.append("[");
- boolean first = true;
- for (Map.Entry<String, Object> e : annotations.entrySet()) {
- if (!first)
- sb.append(", ");
- // @todo remove relation name hack when making relation name a scalar.
- if (Annotations.RELATION_NAME.equals(e.getKey())
- && e.getValue() != null
- && e.getValue().getClass().isArray()) {
- sb.append(e.getKey() + "="
- + Arrays.toString((String[]) e.getValue()));
- } else {
- sb.append(e.getKey() + "=" + e.getValue());
- }
- first = false;
- }
- sb.append("]");
- }
-
+ annotationsToString(sb);
return sb.toString();
}
Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/cost/BTreeCostModel.java
===================================================================
--- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/cost/BTreeCostModel.java 2010-10-01 15:14:05 UTC (rev 3712)
+++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/cost/BTreeCostModel.java 2010-10-01 15:36:09 UTC (rev 3713)
@@ -26,9 +26,13 @@
*/
package com.bigdata.bop.cost;
+import java.text.NumberFormat;
+
import com.bigdata.btree.AbstractBTree;
import com.bigdata.btree.BTree;
-import com.bigdata.journal.IIndexManager;
+import com.bigdata.btree.BTreeUtilizationReport;
+import com.bigdata.btree.IBTreeStatistics;
+import com.bigdata.btree.IBTreeUtilizationReport;
import com.bigdata.journal.Journal;
/**
@@ -52,43 +56,71 @@
*/
public class BTreeCostModel {
+ private final DiskCostModel diskCostModel;
+
/**
+ *
+ * @param diskCostModel
+ * The cost model for the disk on which the {@link Journal}
+ * backing the {@link BTree} is located.
+ */
+ public BTreeCostModel(final DiskCostModel diskCostModel) {
+
+ if (diskCostModel == null)
+ throw new IllegalArgumentException();
+
+ this.diskCostModel = diskCostModel;
+
+ }
+
+ /**
+ * Compute the height of the B+Tree from its entry count and branching
+ * factor (this can also be used to find the minimum height at which there
+ * could exist a given range count).
+ */
+ static public int estimateHeight(final int entryCount,
+ final int branchingFactor) {
+
+ if (entryCount < branchingFactor)
+ return 0;
+
+ final double logm = Math.log(branchingFactor);
+
+ final double logn = Math.log(entryCount);
+
+ final double h = (logm / logn) - 1;
+
+ return (int) Math.ceil(h);
+
+ }
+
+ /**
* Return the estimated cost of a range scan of the index.
*
- * @param diskCostModel
- * The cost model for the disk.
* @param rangeCount
* The range count for the scan.
- * @param btree
- * The index.
+ * @param m
+ * The B+Tree branching factor.
+ * @param h
+ * The B+Tree height.
+ * @param leafUtilization
+ * The leaf utilization percentage [0:100].
*
* @return The estimated cost (milliseconds).
- *
- * @todo how to get the right view onto the BTree without locking? or raise
- * the cost model into the {@link IIndexManager}?
*/
- public double rangeScan(final DiskCostModel diskCostModel,
- final int rangeCount, final BTree btree) {
+ public double rangeScan(final long rangeCount, final int m, final int h,
+ final int leafUtilization) {
if (rangeCount == 0)
return 0d;
- // double height = (Math.log(branchingFactor) / Math.log(entryCount)) -
- // 1;
-
- final int m = btree.getBranchingFactor();
-
- final int entryCount = btree.getEntryCount();
-
- final int height = btree.getHeight();
-
// average seek time to a leaf.
- final double averageSeekTime = Math.max(0, (height - 1))
+ final double averageSeekTime = Math.max(0, (h - 1))
* diskCostModel.seekTime;
// the percentage of the leaves which are full.
// final double leafFillRate = .70d;
- final double leafFillRate = ((double) btree.getUtilization()[1]) / 100;
+ final double leafFillRate = ((double) leafUtilization) / 100;
/*
* The expected #of leaves to visit for that range scan.
@@ -96,7 +128,7 @@
* Note: There is an edge condition when the root leaf is empty
* (fillRate is zero).
*/
- final double expectedLeafCount = Math.ceil((rangeCount / m)
+ final double expectedLeafCount = Math.ceil((((double) rangeCount) / m)
* Math.min(1, (1 / leafFillRate)));
/*
@@ -110,4 +142,140 @@
}
+ /**
+ * Prints out some tables based on different disk cost models, branching
+ * factors, and range scans. To validate this, you can do a scatter plot of
+ * the rangeCount and cost columns and observe the log linear curve of the
+ * B+Tree.
+ *
+ * @param args
+ * ignored.
+ *
+ * @see <a
+ * href="src/resources/architectures/query-cost-model.xls">query-cost-model.xls</a>
+ */
+ public static void main(String[] args) {
+
+ final DiskCostModel[] diskCostModels = new DiskCostModel[] { DiskCostModel.DEFAULT };
+
+ final int[] branchingFactors = new int[] { 32, 64, 128, 256, 512, 1024 };
+
+ final int[] heights = new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+
+ final int[] rangeCounts = new int[] { 1, 10, 100, 1000, 2000, 5000, 10000, 2000, 50000, 100000 };
+
+ final int leafUtilization = 65; // average percent "full" per leaf.
+
+ System.out.println("seekTime\txferRate\tleafUtil\tm\theight\trangeCount\tcost(ms)");
+
+ final NumberFormat millisFormat = NumberFormat.getIntegerInstance();
+ millisFormat.setGroupingUsed(true);
+
+ final NumberFormat percentFormat = NumberFormat.getPercentInstance();
+ percentFormat.setMinimumFractionDigits(0);
+
+ final StringBuilder sb = new StringBuilder();
+
+ for (DiskCostModel diskCostModel : diskCostModels) {
+
+ final BTreeCostModel btreeCostModel = new BTreeCostModel(
+ diskCostModel);
+
+ for (int m : branchingFactors) {
+
+ for (int h : heights) {
+
+ for (int rangeCount : rangeCounts) {
+
+ final int estimatedHeight = estimateHeight(rangeCount,
+ m);
+
+ if (estimatedHeight > h) {
+ /*
+ * Skip range counts which are too large for the
+ * current B+Tree height.
+ */
+ break;
+ }
+
+ final double cost = btreeCostModel.rangeScan(
+ rangeCount, m, h, leafUtilization);
+
+ sb.setLength(0); // reset.
+ sb.append(millisFormat.format(diskCostModel.seekTime));
+ sb.append('\t');
+ sb.append(millisFormat
+ .format(diskCostModel.transferRate));
+ sb.append('\t');
+ sb.append(percentFormat.format(leafUtilization / 100d));
+ sb.append('\t');
+ sb.append(m);
+ sb.append('\t');
+ sb.append(h);
+ sb.append('\t');
+ sb.append(rangeCount);
+ sb.append('\t');
+ sb.append(millisFormat.format(cost));
+ System.out.println(sb);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ private static class MockBTreeStatistics implements IBTreeStatistics {
+
+ private final int m;
+
+ private final int entryCount;
+
+ private final int height;
+
+ private final int leafCount;
+
+ private final int nodeCount;
+
+ private final IBTreeUtilizationReport utilReport;
+
+ public MockBTreeStatistics(final int m, final int entryCount,
+ final int height, final int leafCount, final int nodeCount) {
+ this.m = m;
+ this.entryCount = entryCount;
+ this.height = height;
+ this.leafCount = leafCount;
+ this.nodeCount = nodeCount;
+ this.utilReport = new BTreeUtilizationReport(this);
+ }
+
+ public int getBranchingFactor() {
+ return m;
+ }
+
+ public int getEntryCount() {
+ return entryCount;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public int getLeafCount() {
+ return leafCount;
+ }
+
+ public int getNodeCount() {
+ return nodeCount;
+ }
+
+ public IBTreeUtilizationReport getUtilization() {
+ return utilReport;
+ }
+
+ }
+
}
Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/cost/DiskCostModel.java
===================================================================
--- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/cost/DiskCostModel.java 2010-10-01 15:14:05 UTC (rev 3712)
+++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/cost/DiskCostModel.java 2010-10-01 15:36:09 UTC (rev 3713)
@@ -47,16 +47,24 @@
*/
final public double seekTime;
+ /**
+ * The average disk transfer rate (megabytes per second).
+ */
final public double transferRate;
/**
*
* @param seekTime
+ * The average disk seek time (milliseconds).
* @param transferRate
+ * The average disk transfer rate (megabytes per second).
*/
public DiskCostModel(double seekTime, double transferRate) {
+
this.seekTime = seekTime;
+
this.transferRate = transferRate;
+
}
}
Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/cost/IndexSegmentCostModel.java
===================================================================
--- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/cost/IndexSegmentCostModel.java 2010-10-01 15:14:05 UTC (rev 3712)
+++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/cost/IndexSegmentCostModel.java 2010-10-01 15:36:09 UTC (rev 3713)
@@ -37,15 +37,27 @@
*
* @author <a href="mailto:tho...@us...">Bryan Thompson</a>
* @version $Id$
- *
- * @todo
*/
public class IndexSegmentCostModel {
+ private final DiskCostModel diskCostModel;
+
/**
*
* @param diskCostModel
* The disk cost model.
+ */
+ public IndexSegmentCostModel(final DiskCostModel diskCostModel) {
+
+ if (diskCostModel == null)
+ throw new IllegalArgumentException();
+
+ this.diskCostModel = diskCostModel;
+
+ }
+
+ /**
+ *
* @param rangeCount
* The range count for the index scan.
* @param branchingFactor
@@ -58,8 +70,7 @@
*
* @return The estimated time for the range scan (milliseconds).
*/
- public double rangeScan(final DiskCostModel diskCostModel,
- final int rangeCount, final int branchingFactor,
+ public double rangeScan(final int rangeCount, final int branchingFactor,
final int averageBytesPerLeaf, final int xferBufferSize) {
if (rangeCount == 0)
Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/QueryEngine.java
===================================================================
--- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/QueryEngine.java 2010-10-01 15:14:05 UTC (rev 3712)
+++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/QueryEngine.java 2010-10-01 15:36:09 UTC (rev 3713)
@@ -42,12 +42,24 @@
import org.apache.log4j.Logger;
import com.bigdata.bop.BOp;
+import com.bigdata.bop.BOpContextBase;
+import com.bigdata.bop.IBindingSet;
import com.bigdata.bop.PipelineOp;
-import com.bigdata.bop.IBindingSet;
+import com.bigdata.bop.ap.Predicate;
+import com.bigdata.bop.cost.BTreeCostModel;
+import com.bigdata.bop.cost.DiskCostModel;
+import com.bigdata.btree.AbstractBTree;
import com.bigdata.btree.BTree;
+import com.bigdata.btree.IBTreeStatistics;
import com.bigdata.btree.IndexSegment;
+import com.bigdata.btree.UnisolatedReadWriteIndex;
import com.bigdata.btree.view.FusedView;
import com.bigdata.journal.IIndexManager;
+import com.bigdata.journal.Journal;
+import com.bigdata.journal.NoSuchIndexException;
+import com.bigdata.journal.TimestampUtility;
+import com.bigdata.relation.IRelation;
+import com.bigdata.relation.accesspath.IAccessPath;
import com.bigdata.resources.IndexManager;
import com.bigdata.service.IBigdataFederation;
import com.bigdata.service.IDataService;
@@ -771,4 +783,78 @@
// NOP
}
+ /*
+ * Cost models.
+ */
+
+ /**
+ * The cost model associated with the disk on which the indices are stored.
+ * For a {@link Journal}, this is just the cost model of the backing disk.
+ * For the federation, this should be an average cost model.
+ *
+ * @todo This is not parameterized. A simple cost model is always assumed.
+ * The correct cost model is necessary in order to get the tradeoff
+ * point right for SCAN+FILTER versus SUBQUERY on SSD or RAID arrays
+ * with lots of spindles versus normal disk.
+ *
+ * @todo In a shared disk deployment, we might introduce one cost model for
+ * local SSD used to cache journals, one for local non-SSD disks used
+ * to cache index segments, and one for remote storage used to
+ * materialize historical journals and index segments for query.
+ *
+ * @todo In a federation, this should be reported out as metadata for the
+ * federation. Perhaps as a Jini attribute.
+ */
+ private static final DiskCostModel diskCostModel = DiskCostModel.DEFAULT;
+
+ /**
+ * Return an estimate of the cost of a scan on the predicate.
+ *
+ * @param pred
+ * The predicate.
+ *
+ * @return The estimated cost of a scan on that predicate.
+ *
+ * @todo This tunnels through to the {@link AbstractBTree} class and is thus
+ * specific to standalone and also may run into trouble once we
+ * support unisolated access paths for reads or mutation since it may
+ * encounter an {@link UnisolatedReadWriteIndex} instead of an
+ * {@link AbstractBTree}.
+ */
+ public <E> double estimateCost(final BOpContextBase context,
+ final Predicate<E> pred) {
+
+ final IRelation<E> r = context.getRelation(pred);
+
+ final IAccessPath<E> ap = context.getAccessPath(r, pred);
+
+ final long rangeCount = ap.rangeCount(false/* exact */);
+
+ /*
+ * Drill through to the actual index object on the local index manager
+ * (standalone only). This avoids the UnisolatedReadWriteIndex class
+ * used to protect the index from concurrent modifications.
+ */
+ final String name = pred.getOnlyRelationName() + "."
+ + pred.getKeyOrder();
+
+ final long timestamp = (Long) pred
+ .getRequiredProperty(BOp.Annotations.TIMESTAMP);
+
+ final AbstractBTree index = (AbstractBTree) getIndexManager().getIndex(
+ name, timestamp);
+
+ if (index == null)
+ throw new NoSuchIndexException(name + ", timestamp="
+ + TimestampUtility.toString(timestamp));
+
+ final IBTreeStatistics stats = index.getStatistics();
+
+ final double cost = new BTreeCostModel(diskCostModel).rangeScan(
+ rangeCount, stats.getBranchingFactor(), stats.getHeight(),
+ stats.getUtilization().getLeafUtilization());
+
+ return cost;
+ }
+
}
Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/Rule2BOpUtility.java
===================================================================
--- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/Rule2BOpUtility.java 2010-10-01 15:14:05 UTC (rev 3712)
+++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/Rule2BOpUtility.java 2010-10-01 15:36:09 UTC (rev 3713)
@@ -28,6 +28,7 @@
package com.bigdata.bop.engine;
import java.io.Serializable;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -47,17 +48,24 @@
import com.bigdata.bop.BOpEvaluationContext;
import com.bigdata.bop.BOpUtility;
import com.bigdata.bop.Constant;
+import com.bigdata.bop.HashBindingSet;
+import com.bigdata.bop.IBindingSet;
+import com.bigdata.bop.IConstant;
import com.bigdata.bop.IConstraint;
import com.bigdata.bop.IPredicate;
import com.bigdata.bop.IVariable;
+import com.bigdata.bop.IVariableOrConstant;
import com.bigdata.bop.NV;
import com.bigdata.bop.PipelineOp;
+import com.bigdata.bop.Var;
import com.bigdata.bop.ap.Predicate;
import com.bigdata.bop.bset.StartOp;
import com.bigdata.bop.join.PipelineJoin;
import com.bigdata.bop.rdf.join.DataSetJoin;
import com.bigdata.bop.solutions.SliceOp;
import com.bigdata.rdf.internal.IV;
+import com.bigdata.rdf.internal.TermId;
+import com.bigdata.rdf.internal.VTE;
import com.bigdata.rdf.lexicon.LexiconRelation;
import com.bigdata.rdf.model.BigdataURI;
import com.bigdata.rdf.sail.BigdataEvaluationStrategyImpl;
@@ -68,6 +76,7 @@
import com.bigdata.rdf.spo.NamedGraphSolutionExpander;
import com.bigdata.rdf.store.AbstractTripleStore;
import com.bigdata.rdf.store.IRawTripleStore;
+import com.bigdata.relation.IRelation;
import com.bigdata.relation.accesspath.ElementFilter;
import com.bigdata.relation.accesspath.IElementFilter;
import com.bigdata.relation.rule.IProgram;
@@ -76,6 +85,7 @@
import com.bigdata.relation.rule.eval.DefaultEvaluationPlan2;
import com.bigdata.relation.rule.eval.IRangeCountFactory;
import com.bigdata.relation.rule.eval.RuleState;
+import com.bigdata.striterator.IKeyOrder;
/**
* Utility class converts {@link IRule}s to {@link BOp}s.
@@ -168,16 +178,23 @@
* The estimated cost of a SCAN + FILTER approach to a default graph or
* named graph query.
*/
- String COST_SCAN = Rule2BOpUtility.class.getName() + ".costScan";
+ String COST_SCAN = Rule2BOpUtility.class.getName() + ".cost.scan";
/**
* The estimated cost of a SUBQUERY approach to a default graph or named
* graph query.
*/
String COST_SUBQUERY = Rule2BOpUtility.class.getName()
- + ".costSubquery";
+ + ".cost.subquery";
/**
+ * The #of samples used when estimating the cost of a SUBQUERY approach
+ * to a default graph or named graph query.
+ */
+ String COST_SUBQUERY_SAMPLE_COUNT = Rule2BOpUtility.class.getName()
+ + ".cost.subquerySampleCount";
+
+ /**
* The #of known graphs in the {@link Dataset} for a default graph or
* named graph query.
*/
@@ -254,7 +271,14 @@
// evaluation plan order.
final int[] order = plan.getOrder();
- // variables to be retained for each join.
+ // the #of variables in each tail of the rule.
+ final int[] nvars = new int[rule.getTailCount()];
+
+ // the index assigned to each tail of the rule.
+ final IKeyOrder[] keyOrder = computeKeyOrderForEachTail(rule, context,
+ order, nvars);
+
+ // the variables to be retained for each join.
final IVariable[][] selectVars = RuleState
.computeRequiredVarsForEachTail(rule, order);
@@ -304,6 +328,9 @@
// assign a bop id to the predicate
Predicate<?> pred = (Predicate<?>) rule.getTail(order[i]).setBOpId(
bopId++);
+
+ // decorate the predicate with the assigned index.
+ pred = pred.setKeyOrder(keyOrder[order[i]]);
/*
* Collect all the constraints for this predicate based on which
@@ -361,6 +388,9 @@
final boolean quads = pred.getProperty(Annotations.QUADS,
Annotations.DEFAULT_QUADS);
+ // pull of the Sesame dataset before we strip the annotations.
+ final Dataset dataset = (Dataset) pred.getProperty(Annotations.DATASET);
+
// strip off annotations that we do not want to propagate.
pred = pred.clearAnnotations(ANNS_TO_CLEAR_FROM_PREDICATE);
@@ -380,12 +410,12 @@
switch (scope) {
case NAMED_CONTEXTS:
- left = namedGraphJoin(queryEngine, left, anns, pred,
- cvar);
+ left = namedGraphJoin(queryEngine, context, left, anns,
+ pred, dataset, cvar);
break;
case DEFAULT_CONTEXTS:
- left = defaultGraphJoin(queryEngine, left, anns, pred,
- cvar);
+ left = defaultGraphJoin(queryEngine, context, left,
+ anns, pred, dataset, cvar);
break;
default:
throw new AssertionError();
@@ -468,11 +498,10 @@
* @return
*/
private static PipelineOp namedGraphJoin(final QueryEngine queryEngine,
- final PipelineOp left, final List<NV> anns, Predicate pred,
+ final BOpContextBase context, final PipelineOp left,
+ final List<NV> anns, Predicate pred, final Dataset dataset,
final org.openrdf.query.algebra.Var cvar) {
- final Dataset dataset = (Dataset) pred.getProperty(Annotations.DATASET);
-
final boolean scaleOut = queryEngine.isScaleOut();
if (scaleOut) {
anns.add(new NV(Predicate.Annotations.EVALUATION_CONTEXT,
@@ -482,8 +511,7 @@
BOpEvaluationContext.ANY));
}
- final DataSetSummary summary = new DataSetSummary(dataset
- .getNamedGraphs());
+ final DataSetSummary summary = new DataSetSummary(dataset.getNamedGraphs());
anns.add(new NV(Annotations.NKNOWN, summary.nknown));
@@ -544,18 +572,41 @@
} else {
/*
- * Estimate cost of SCAN with C unbound)
+ * Estimate cost of SCAN with C unbound.
*/
- final double scanCost = getScanCost(pred);
+ final double scanCost = queryEngine.estimateCost(context, pred);
anns.add(new NV(Annotations.COST_SCAN, scanCost));
/*
- * Estimate cost of SUBQUERY with C bound.
+ * Estimate cost of SUBQUERY with C bound (sampling).
+ *
+ * @todo This should randomly sample in case there is bias in the
+ * order in which the URIs are presented here. However, the only
+ * thing which would be likely to create a strong bias is if someone
+ * sorted them on the IVs or if the URIs were in the same ordering
+ * in which their IVs were assigned AND the data were somehow
+ * correlated with that order. I rate the latter as pretty unlikely
+ * and the former is not true, so this sampling approach should be
+ * pretty good.
+ *
+ * @todo parameter for the #of samples to take.
*/
- final double subqueryCost = getSubqueryCost(pred);
+ double subqueryCost = 0d;
+ final int limit = 100;
+ int nsamples = 0;
+ for (URI uri : summary.graphs) {
+ if (nsamples == limit)
+ break;
+ final IV graph = ((BigdataURI) uri).getIV();
+ subqueryCost += queryEngine.estimateCost(context, pred.asBound(
+ (IVariable) pred.get(3), new Constant(graph)));
+ nsamples++;
+ }
+ subqueryCost /= nsamples;
anns.add(new NV(Annotations.COST_SUBQUERY, subqueryCost));
+ anns.add(new NV(Annotations.COST_SUBQUERY_SAMPLE_COUNT, nsamples));
if (scanCost < subqueryCost * summary.nknown) {
@@ -628,34 +679,6 @@
}
/**
- *
- * @param pred
- * @return
- *
- * FIXME Cost models have been implemented, but are not yet hooked in.
- */
- static double getScanCost(Predicate pred) {
- /*
- * @todo Scan is more expensive on the Journal so this is set to ONE (1)
- * and subquery is set to ZERO (0). This will get replaced by the actual
- * computed costs shortly.
- */
- return 1d;
- }
-
- /**
- *
- * @param pred
- * @return
- *
- * FIXME Cost models have been implemented, but are not yet hooked
- * in.
- */
- static double getSubqueryCost(Predicate pred) {
- return 0d;
- }
-
- /**
* Generate a default graph join (quads mode).
*
* @param queryEngine
@@ -669,7 +692,8 @@
* remote access paths with other remote access paths.
*/
private static PipelineOp defaultGraphJoin(final QueryEngine queryEngine,
- final PipelineOp left, final List<NV> anns, final Predicate pred,
+ final BOpContextBase context, final PipelineOp left,
+ final List<NV> anns, final Predicate pred, final Dataset dataset,
final org.openrdf.query.algebra.Var cvar) {
// @todo decision of local vs remote ap.
@@ -878,4 +902,106 @@
} // DataSetSummary
+ /**
+ * Return an array indicating the {@link IKeyOrder} that will be used when
+ * reading on each of the tail predicates. The array is formed using a
+ * private {@link IBindingSet} and propagating fake bindings to each
+ * predicate in turn using the given evaluation order.
+ *
+ * @param order
+ * The evaluation order.
+ * @param nvars
+ * The #of unbound variables for each tail predicate is assigned
+ * by side-effect.
+ *
+ * @return An array of the {@link IKeyOrder}s for each tail predicate. The
+ * array is correlated with the predicates index in the tail of the
+ * rule NOT its evaluation order.
+ */
+ @SuppressWarnings("unchecked")
+ static private IKeyOrder[] computeKeyOrderForEachTail(final IRule rule,
+ final BOpContextBase context, final int[] order, final int[] nvars) {
+
+ if (order == null)
+ throw new IllegalArgumentException();
+
+ if (order.length != rule.getTailCount())
+ throw new IllegalArgumentException();
+
+ final int tailCount = rule.getTailCount();
+
+ final IKeyOrder[] a = new IKeyOrder[tailCount];
+
+ final IBindingSet bindingSet = new HashBindingSet();
+
+ for (int orderIndex = 0; orderIndex < tailCount; orderIndex++) {
+
+ final int tailIndex = order[orderIndex];
+
+ final IPredicate pred = rule.getTail(tailIndex);
+
+ final IRelation rel = context.getRelation(pred);
+
+ final IPredicate asBound = pred.asBound(bindingSet);
+
+ final IKeyOrder keyOrder = context.getAccessPath(
+ rel, asBound).getKeyOrder();
+
+ if (log.isDebugEnabled())
+ log.debug("keyOrder=" + keyOrder + ", orderIndex=" + orderIndex
+ + ", tailIndex=" + orderIndex + ", pred=" + pred
+ + ", bindingSet=" + bindingSet + ", rule=" + rule);
+
+ // save results.
+ a[tailIndex] = keyOrder;
+ nvars[tailIndex] = keyOrder == null ? asBound.getVariableCount()
+ : asBound.getVariableCount((IKeyOrder) keyOrder);
+
+ final int arity = pred.arity();
+
+ for (int j = 0; j < arity; j++) {
+
+ final IVariableOrConstant<?> t = pred.get(j);
+
+ if (t.isVar()) {
+
+ final Var<?> var = (Var<?>) t;
+
+ if (log.isDebugEnabled()) {
+
+ log.debug("Propagating binding: pred=" + pred
+ + ", var=" + var + ", bindingSet="
+ + bindingSet);
+
+ }
+
+ bindingSet.set(var, fakeTermId);
+
+ }
+
+ }
+
+ }
+
+ if (log.isDebugEnabled()) {
+
+ log.debug("keyOrder[]=" + Arrays.toString(a) + ", nvars="
+ + Arrays.toString(nvars) + ", rule=" + rule);
+
+ }
+
+ return a;
+
+ }
+
+ /**
+ * A fake value that is propagated when we compute the {@link IKeyOrder} for
+ * a series of joins based on an assigned join evaluation order.
+ *
+ * @todo This has to be of the appropriate data type or we run into class
+ * cast exceptions.
+ */
+ final private static transient IConstant<IV> fakeTermId = new Constant<IV>(
+ new TermId(VTE.URI, -1L));
+
}
Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/fed/FederatedQueryEngine.java
===================================================================
--- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/fed/FederatedQueryEngine.java 2010-10-01 15:14:05 UTC (rev 3712)
+++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/fed/FederatedQueryEngine.java 2010-10-01 15:36:09 UTC (rev 3713)
@@ -215,11 +215,27 @@
this.resourceService = resourceService;
if(fed instanceof JiniFederation<?>) {
- // the proxy for this query engine when used as a query controller.
- this.clientProxy = (IQueryClient) ((JiniFederation<?>)fed).getProxy(this, false/*enableDGC*/);
+
+ /*
+ * The proxy for this query engine when used as a query controller.
+ *
+ *
+ * Should the data services expose their query engine in this
+ * manner?
+ *
+ * @todo We need to unexport the proxy as well when the service is
+ * shutdown. This should follow the same pattern as DataService ->
+ * DataServer. E.g., a QueryEngineServer class.
+ */
+
+ this.clientProxy = (IQueryClient) ((JiniFederation<?>) fed)
+ .getProxy(this, false/* enableDGC */);
+
} else {
- // E.g., an EmbeddedFederation in the test suite.
+
+ // E.g., an EmbeddedFederation in the test suite.
this.clientProxy = this;
+
}
}
Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/AbstractBTree.java
===================================================================
--- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/AbstractBTree.java 2010-10-01 15:14:05 UTC (rev 3712)
+++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/AbstractBTree.java 2010-10-01 15:36:09 UTC (rev 3713)
@@ -138,7 +138,7 @@
* @see KeyBuilder
*/
abstract public class AbstractBTree implements IIndex, IAutoboxBTree,
- ILinearList {
+ ILinearList, IBTreeStatistics {
/**
* The index is already closed.
@@ -787,8 +787,7 @@
// the % utilization in [0:1] for the whole tree (nodes + leaves).
counterSet.addCounter("% utilization", new Instrument<Double>(){
protected void sample() {
- final int[] tmp = getUtilization();
- setValue(tmp[2] / 100d);
+ setValue(getUtilization().getTotalUtilization() / 100d);
}
});
@@ -1617,10 +1616,11 @@
return true;
}
-
- /**
- * The branching factor for the btree.
+
+ /*
+ * IBTreeStatistics
*/
+
final public int getBranchingFactor() {
return branchingFactor;
@@ -1636,33 +1636,14 @@
*/
final int minChildren;
- /**
- * The height of the btree. The height is the #of levels minus one. A btree
- * with only a root leaf has <code>height := 0</code>. A btree with a
- * root node and one level of leaves under it has <code>height := 1</code>.
- * Note that all leaves of a btree are at the same height (this is what is
- * means for the btree to be "balanced"). Also note that the height only
- * changes when we split or join the root node (a btree maintains balance by
- * growing and shrinking in levels from the top rather than the leaves).
- */
abstract public int getHeight();
- /**
- * The #of non-leaf nodes in the {@link AbstractBTree}. This is zero (0)
- * for a new btree.
- */
abstract public int getNodeCount();
- /**
- * The #of leaf nodes in the {@link AbstractBTree}. This is one (1) for a
- * new btree.
- */
abstract public int getLeafCount();
/**
- * The #of entries (aka values) in the {@link AbstractBTree}. This is zero
- * (0) for a new B+Tree. Note that this value is tracked explicitly so it
- * requires no IOs.
+ * {@inheritDoc}
*
* @todo this could be re-defined as the exact entry count if we tracked the
* #of deleted index entries and subtracted that from the total #of
@@ -1677,6 +1658,21 @@
abstract public int getEntryCount();
/**
+ * Return a statistics snapshot of the B+Tree.
+ */
+ public IBTreeStatistics getStatistics() {
+
+ return new BTreeStatistics(this);
+
+ }
+
+ public IBTreeUtilizationReport getUtilization() {
+
+ return new BTreeUtilizationReport(this);
+
+ }
+
+ /**
* The object responsible for (de-)serializing the nodes and leaves of the
* {@link IIndex}.
*/
@@ -3197,47 +3193,6 @@
// abstract public ILeafCursor newLeafCursor(ILeafCursor leafCursor);
/**
- * Computes and returns the utilization of the tree. The utilization figures
- * do not factor in the space requirements of nodes and leaves.
- *
- * @return An array whose elements are:
- * <ul>
- * <li>0 - the leaf utilization percentage [0:100]. The leaf
- * utilization is computed as the #of values stored in the tree
- * divided by the #of values that could be stored in the #of
- * allocated leaves.</li>
- * <li>1 - the node utilization percentage [0:100]. The node
- * utilization is computed as the #of non-root nodes divided by the
- * #of non-root nodes that could be addressed by the tree.</li>
- * <li>2 - the total utilization percentage [0:100]. This is the
- * average of the leaf utilization and the node utilization.</li>
- * </ul>
- */
- public int[] getUtilization() {
-
- final int nnodes = getNodeCount();
-
- final int nleaves = getLeafCount();
-
- final int nentries = getEntryCount();
-
- final int numNonRootNodes = nnodes + nleaves - 1;
-
- final int branchingFactor = getBranchingFactor();
-
- final int nodeUtilization = nnodes == 0 ? 100 : (100 * numNonRootNodes)
- / (nnodes * branchingFactor);
-
- final int leafUtilization = (100 * nentries)
- / (nleaves * branchingFactor);
-
- final int utilization = (nodeUtilization + leafUtilization) / 2;
-
- return new int[] { nodeUtilization, leafUtilization, utilization };
-
- }
-
- /**
* Recursive dump of the tree.
*
* @param out
@@ -3256,7 +3211,7 @@
// True iff we will write out the node structure.
final boolean info = level.toInt() <= Level.INFO.toInt();
- final int[] utils = getUtilization();
+ final IBTreeUtilizationReport utils = getUtilization();
if (info) {
@@ -3273,8 +3228,9 @@
out.println("height=" + height + ", branchingFactor="
+ branchingFactor + ", #nodes=" + nnodes + ", #leaves="
+ nleaves + ", #entries=" + nentries + ", nodeUtil="
- + utils[0] + "%, leafUtil=" + utils[1] + "%, utilization="
- + utils[2] + "%");
+ + utils.getNodeUtilization() + "%, leafUtil="
+ + utils.getLeafUtilization() + "%, utilization="
+ + utils.getTotalUtilization() + "%");
}
if (root != null) {
Added: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/BTreeStatistics.java
===================================================================
--- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/BTreeStatistics.java (rev 0)
+++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/BTreeStatistics.java 2010-10-01 15:36:09 UTC (rev 3713)
@@ -0,0 +1,90 @@
+/**
+
+Copyright (C) SYSTAP, LLC 2006-2010. All rights reserved.
+
+Contact:
+ SYSTAP, LLC
+ 4501 Tower Road
+ Greensboro, NC 27410
+ lic...@bi...
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+ * Created on Oct 1, 2010
+ */
+
+package com.bigdata.btree;
+
+import java.io.Serializable;
+
+/**
+ * A snapshot of the B+Tree statistics.
+ *
+ * @author <a href="mailto:tho...@us...">Bryan Thompson</a>
+ * @version $Id$
+ */
+public class BTreeStatistics implements IBTreeStatistics, Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ private final int m;
+
+ private final int entryCount;
+
+ private final int height;
+
+ private final int leafCount;
+
+ private final int nodeCount;
+
+ private final IBTreeUtilizationReport utilReport;
+
+ public BTreeStatistics(final AbstractBTree btree) {
+ this.m = btree.getBranchingFactor();
+ this.entryCount = btree.getEntryCount();
+ this.height = btree.getHeight();
+ this.leafCount = btree.getLeafCount();
+ this.nodeCount = btree.getNodeCount();
+ this.utilReport = btree.getUtilization();
+ }
+
+ public int getBranchingFactor() {
+ return m;
+ }
+
+ public int getEntryCount() {
+ return entryCount;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public int getLeafCount() {
+ return leafCount;
+ }
+
+ public int getNodeCount() {
+ return nodeCount;
+ }
+
+ public IBTreeUtilizationReport getUtilization() {
+ return utilReport;
+ }
+
+}
Property changes on: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/BTreeStatistics.java
___________________________________________________________________
Added: svn:keywords
+ Id Date Revision Author HeadURL
Added: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/BTreeUtilizationReport.java
===================================================================
--- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/BTreeUtilizationReport.java (rev 0)
+++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/BTreeUtilizationReport.java 2010-10-01 15:36:09 UTC (rev 3713)
@@ -0,0 +1,85 @@
+/**
+
+Copyright (C) SYSTAP, LLC 2006-2010. All rights reserved.
+
+Contact:
+ SYSTAP, LLC
+ 4501 Tower Road
+ Greensboro, NC 27410
+ lic...@bi...
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+ * Created on Oct 1, 2010
+ */
+
+package com.bigdata.btree;
+
+import java.io.Serializable;
+
+/**
+ * A btree utilization report.
+ *
+ * @author <a href="mailto:tho...@us...">Bryan Thompson</a>
+ * @version $Id$
+ */
+public class BTreeUtilizationReport implements IBTreeUtilizationReport,
+ Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ private final int leafUtilization;
+
+ private final int nodeUtilization;
+
+ private final int totalUtilization;
+
+ public BTreeUtilizationReport(final IBTreeStatistics stats) {
+
+ final int nnodes = stats.getNodeCount();
+
+ final int nleaves = stats.getLeafCount();
+
+ final int nentries = stats.getEntryCount();
+
+ final int numNonRootNodes = nnodes + nleaves - 1;
+
+ final int branchingFactor = stats.getBranchingFactor();
+
+ nodeUtilization = nnodes == 0 ? 100 : (100 * numNonRootNodes)
+ / (nnodes * branchingFactor);
+
+ leafUtilization = (100 * nentries) / (nleaves * branchingFactor);
+
+ totalUtilization = (nodeUtilization + leafUtilization) / 2;
+
+ }
+
+ public int getLeafUtilization() {
+ return leafUtilization;
+ }
+
+ public int getNodeUtilization() {
+ return nodeUtilization;
+ }
+
+ public int getTotalUtilization() {
+ return totalUtilization;
+ }
+
+}
Property changes on: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/BTreeUtilizationReport.java
___________________________________________________________________
Added: svn:keywords
+ Id Date Revision Author HeadURL
Added: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/IBTreeStatistics.java
===================================================================
--- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/IBTreeStatistics.java (rev 0)
+++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/IBTreeStatistics.java 2010-10-01 15:36:09 UTC (rev 3713)
@@ -0,0 +1,83 @@
+/**
+
+Copyright (C) SYSTAP, LLC 2006-2010. All rights reserved.
+
+Contact:
+ SYSTAP, LLC
+ 4501 Tower Road
+ Greensboro, NC 27410
+ lic...@bi...
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+ * Created on Oct 1, 2010
+ */
+
+package com.bigdata.btree;
+
+/**
+ * Interface used to report out some statistics about a B+Tree. These statistics
+ * may be used in combination with a disk cost model to predict the cost
+ * (latency) associated with a variety of operations on the B+Tree. All values
+ * reported by this interface are tracked explicitly by the
+ * {@link AbstractBTree} and do not require DISK IO.
+ *
+ * @author <a href="mailto:tho...@us...">Bryan Thompson</a>
+ * @version $Id$
+ */
+public interface IBTreeStatistics {
+
+ /**
+ * The branching factor for the btree.
+ */
+ int getBranchingFactor();
+
+ /**
+ * The height of the btree. The height is the #of levels minus one. A btree
+ * with only a root leaf has <code>height := 0</code>. A btree with a
+ * root node and one level of leaves under it has <code>height := 1</code>.
+ * Note that all leaves of a btree are at the same height (this is what is
+ * means for the btree to be "balanced"). Also note that the height only
+ * changes when we split or join the root node (a btree maintains balance by
+ * growing and shrinking in levels from the top rather than the leaves).
+ */
+ int getHeight();
+
+ /**
+ * The #of non-leaf nodes in the {@link AbstractBTree}. This is zero (0)
+ * for a new btree.
+ */
+ int getNodeCount();
+
+ /**
+ * The #of leaf nodes in the {@link AbstractBTree}. This is one (1) for a
+ * new btree.
+ */
+ int getLeafCount();
+
+ /**
+ * The #of entries (aka tuples) in the {@link AbstractBTree}. This is zero
+ * (0) for a new B+Tree. When the B+Tree supports delete markers, this value
+ * also includes tuples which have been marked as deleted.
+ */
+ int getEntryCount();
+
+ /**
+ * Computes and returns the utilization of the tree. The utilization figures
+ * do not factor in the space requirements of nodes and leaves.
+ */
+ IBTreeUtilizationReport getUtilization();
+
+}
Property changes on: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/IBTreeStatistics.java
___________________________________________________________________
Added: svn:keywords
+ Id Date Revision Author HeadURL
Added: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/IBTreeUtilizationReport.java
===================================================================
--- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/IBTreeUtilizationReport.java (rev 0)
+++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/IBTreeUtilizationReport.java 2010-10-01 15:36:09 UTC (rev 3713)
@@ -0,0 +1,58 @@
+/**
+
+Copyright (C) SYSTAP, LLC 2006-2010. All rights reserved.
+
+Contact:
+ SYSTAP, LLC
+ 4501 Tower Road
+ Greensboro, NC 27410
+ lic...@bi...
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+ * Created on Oct 1, 2010
+ */
+
+package com.bigdata.btree;
+
+/**
+ * B+Tree utilization report.
+ *
+ * @author <a href="mailto:tho...@us...">Bryan Thompson</a>
+ * @version $Id$
+ */
+public interface IBTreeUtilizationReport {
+
+ /**
+ * The leaf utilization percentage [0:100]. The leaf utilization is computed
+ * as the #of values stored in the tree divided by the #of values that could
+ * be stored in the #of allocated leaves.
+ */
+ int getLeafUtilization();
+
+ /**
+ * The node utilization percentage [0:100]. The node utilization is computed
+ * as the #of non-root nodes divided by the #of non-root nodes that could be
+ * addressed by the tree.
+ */
+ int getNodeUtilization();
+
+ /**
+ * The total utilization percentage [0:100]. This is the average of the leaf
+ * utilization and the node utilization.
+ */
+ int getTotalUtilization();
+
+}
Property changes on: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/IBTreeUtilizationReport.java
___________________________________________________________________
Added: svn:keywords
+ Id Date Revision Author HeadURL
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|