
com.bigdata.resources.BuildViewMetadata Maven / Gradle / Ivy
Show all versions of bigdata-core Show documentation
package com.bigdata.resources;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.bigdata.btree.AbstractBTree;
import com.bigdata.btree.BTree;
import com.bigdata.btree.ILocalBTreeView;
import com.bigdata.btree.IndexSegment;
import com.bigdata.btree.view.FusedView;
import com.bigdata.service.Event;
/**
* Helper class examines an index partition view and returns a view for which we
* can quickly do an incremental build. The given view is always the real index
* partition view. The identified view will include one or more of the sources
* in the given view. The first component of the given view is always included
* in the identified view and will be the {@link BTree} from a journal.
* Additional sources are incorporated into the identified view until the
* specified thresholds would be exceeded. The sources are ordered and the order
* of the sources is maintained. If all sources can be incorporated without
* exceeding the specified thresholds, then the view is flagged as a compacting
* merge rather than an incremental build and deleted tuples will be purged from
* the view.
*
* For example, given a view with a {@link BTree} on a journal followed by 2
* {@link IndexSegment}s, the output view might include just the {@link BTree}
* or the {@link BTree} followed by the first {@link IndexSegment}, or the
* {@link BTree} followed by both of the {@link IndexSegment}s.
*
* @author Bryan Thompson
* @version $Id$
*/
class BuildViewMetadata {
/**
* The maximum #of bytes of {@link IndexSegment}s to allow into the view
* (from the ctor).
*/
public final long maxSumSegBytes;
/** #of sources in the given view. */
public final int nsources;
/** #of sources in the accepted view. */
public final int naccepted;
/**
* true
iff all sources were incorporated into the accepted
* view, in which case the build will be a compacting merge and deleted
* tuples will be purged.
*/
public final boolean compactingMerge;
/** #of journals incorporated into the accepted view. */
public final int journalCount;
/** #of index segments incorporated into the accepted view. */
public final int segmentCount;
/**
* The sum of the entryCount for each source incorporated into the accepted
* view. The entryCount will reflect both deleted and undeleted tuples for
* that source. There may also exist a tuple for the same key in more than
* one source. Therefore this does not give the #of distinct tuples in the
* accepted view.
*/
public final long sumEntryCount;
/**
* The #of bytes in the index segments incorporated into the accepted view.
*/
public final long sumSegBytes;
/**
* The accepted view.
*/
public final ILocalBTreeView acceptedView;
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append("{nsources="+nsources);
sb.append(",naccepted="+naccepted);
sb.append(",compactingMerge="+compactingMerge);
sb.append(",journalCount="+journalCount);
sb.append(",segmentCount="+segmentCount);
sb.append(",sumEntryCount="+sumEntryCount);
sb.append(",sumSegBytes="+sumSegBytes);
sb.append("}");
return sb.toString();
}
/**
* Figure out which sources we want to include. We MUST always include the
* 1st source in the view since that is the mutable BTree on the old
* journal. We continue to include sources in the view until incorporating a
* source into the view would exceed the specified thresholds. We stop there
* because the goal is to keep down the #of components in the view without
* doing the heavy work of processing a large source (which winds up copying
* a lot of tuples). We only do that additional work when a compacting merge
* was selected as the action rather than an incremental build.
*
* @param src
* The source view.
* @param maxSumSegBytes
* The maximum #of index segment bytes that will be incorporated
* into the accepted view.
* @param parentEvent
* The parent event.
*/
public BuildViewMetadata(final ILocalBTreeView src,
final long maxSumSegBytes, final Event parentEvent) {
if (src == null)
throw new IllegalArgumentException();
if (maxSumSegBytes < 0)
throw new IllegalArgumentException();
final Event e = parentEvent.newSubEvent(OverflowSubtaskEnum.ChooseView)
.start();
try {
this.maxSumSegBytes = maxSumSegBytes;
final AbstractBTree[] sources = src.getSources();
this.nsources = sources.length;
final List accepted = new ArrayList(
nsources);
// the mutable BTree on the old journal.
accepted.add(sources[0]);
int journalCount = 1;
int segmentCount = 0;
long sumEntryCount = sources[0].getEntryCount();
long sumSegBytes = 0L;
for (int i = 1; i < sources.length; i++) {
/*
* Values for this source (2nd+ source only).
*/
final AbstractBTree s = sources[i];
final long entryCount = s.getEntryCount();
final boolean isJournal = !(s instanceof IndexSegment);
final long segBytes = (isJournal ? 0L : s.getStore().size());
/*
* Terminate if too much data to include in an incremental
* build.
*/
// final int BUILD_MAX_JOURNAL_COUNT = 3;
// final long BUILD_MAX_SUM_ENTRY_COUNT = Bytes.megabyte * 10;
// if (journalCount > BUILD_MAX_JOURNAL_COUNT)
// break;
// if (sumEntryCount > BUILD_MAX_SUM_ENTRY_COUNT)
// break;
if (sumSegBytes + segBytes > maxSumSegBytes)
break;
/*
* Update the running totals.
*/
sumEntryCount += entryCount;
if (isJournal)
journalCount++;
else
segmentCount++;
sumSegBytes += segBytes;
// accept another source into the view for the build.
accepted.add(s);
}
/*
* Set final totals on the instance fields.
*/
this.journalCount = journalCount;
this.segmentCount = segmentCount;
this.sumEntryCount = sumEntryCount;
this.sumSegBytes = sumSegBytes;
/*
* Note: If ALL sources are accepted, then we are actually doing a
* compacting merge and we set the flag appropriately!
*/
compactingMerge = accepted.size() == sources.length;
naccepted = accepted.size();
/*
* Create the accepted view.
*/
if (naccepted == 1) {
acceptedView = (BTree) accepted.get(0);
} else {
acceptedView = new FusedView(accepted
.toArray(new AbstractBTree[naccepted]));
}
e.addDetails(getParams());
} finally {
e.end();
}
}
public Map getParams() {
final Map m = new HashMap();
m.put("maxSumSegBytes", maxSumSegBytes);
m.put("nsources", nsources);
m.put("naccepted", naccepted);
m.put("compactingMerge", compactingMerge);
m.put("journalCount", journalCount);
m.put("segmentCount", segmentCount);
m.put("sumEntryCount", sumEntryCount);
m.put("sumSegBytes", sumSegBytes);
return m;
}
}