blob: 0890e39ad029637c675d53545d54439cd7823734 [file] [log] [blame]
/*
* Copyright (C) 2011, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.eclipse.jgit.storage.dht;
import org.eclipse.jgit.lib.Config;
/** Options controlling how objects are read from a DHT stored repository. */
public class DhtReaderOptions {
/** 1024 (number of bytes in one kibibyte/kilobyte) */
public static final int KiB = 1024;
/** 1024 {@link #KiB} (number of bytes in one mebibyte/megabyte) */
public static final int MiB = 1024 * KiB;
private Timeout timeout;
private boolean prefetchFollowEdgeHints;
private int prefetchLimit;
private int objectIndexConcurrentBatches;
private int objectIndexBatchSize;
private int deltaBaseCacheSize;
private int deltaBaseCacheLimit;
private int recentInfoCacheSize;
private int recentChunkCacheSize;
private boolean trackFirstChunkLoad;
/** Create a default reader configuration. */
public DhtReaderOptions() {
setTimeout(Timeout.seconds(5));
setPrefetchFollowEdgeHints(true);
setPrefetchLimit(5 * MiB);
setObjectIndexConcurrentBatches(2);
setObjectIndexBatchSize(512);
setDeltaBaseCacheSize(1024);
setDeltaBaseCacheLimit(10 * MiB);
setRecentInfoCacheSize(4096);
setRecentChunkCacheSize(4);
}
/** @return default timeout to wait on long operations before aborting. */
public Timeout getTimeout() {
return timeout;
}
/**
* Set the default timeout to wait on long operations.
*
* @param maxWaitTime
* new wait time.
* @return {@code this}
*/
public DhtReaderOptions setTimeout(Timeout maxWaitTime) {
if (maxWaitTime == null || maxWaitTime.getTime() < 0)
throw new IllegalArgumentException();
timeout = maxWaitTime;
return this;
}
/** @return if the prefetcher should follow edge hints (experimental) */
public boolean isPrefetchFollowEdgeHints() {
return prefetchFollowEdgeHints;
}
/**
* Enable (or disable) the experimental edge following feature.
*
* @param follow
* true to follow the edge hints.
* @return {@code this}
*/
public DhtReaderOptions setPrefetchFollowEdgeHints(boolean follow) {
prefetchFollowEdgeHints = follow;
return this;
}
/** @return number of bytes to load during prefetching. */
public int getPrefetchLimit() {
return prefetchLimit;
}
/**
* Set the number of bytes the prefetcher should hold onto.
*
* @param maxBytes
* @return {@code this}
*/
public DhtReaderOptions setPrefetchLimit(int maxBytes) {
prefetchLimit = Math.max(1024, maxBytes);
return this;
}
/** @return number of concurrent reads against ObjectIndexTable. */
public int getObjectIndexConcurrentBatches() {
return objectIndexConcurrentBatches;
}
/**
* Set the number of concurrent readers on ObjectIndexTable.
*
* @param batches
* number of batches.
* @return {@code this}
*/
public DhtReaderOptions setObjectIndexConcurrentBatches(int batches) {
objectIndexConcurrentBatches = Math.max(1, batches);
return this;
}
/** @return number of objects to lookup in one batch. */
public int getObjectIndexBatchSize() {
return objectIndexBatchSize;
}
/**
* Set the number of objects to lookup at once.
*
* @param objectCnt
* the number of objects in a lookup batch.
* @return {@code this}
*/
public DhtReaderOptions setObjectIndexBatchSize(int objectCnt) {
objectIndexBatchSize = Math.max(1, objectCnt);
return this;
}
/** @return size of the delta base cache hash table, in object entries. */
public int getDeltaBaseCacheSize() {
return deltaBaseCacheSize;
}
/**
* Set the size of the delta base cache hash table.
*
* @param slotCnt
* number of slots in the hash table.
* @return {@code this}
*/
public DhtReaderOptions setDeltaBaseCacheSize(int slotCnt) {
deltaBaseCacheSize = Math.max(1, slotCnt);
return this;
}
/** @return maximum number of bytes to hold in per-reader DeltaBaseCache. */
public int getDeltaBaseCacheLimit() {
return deltaBaseCacheLimit;
}
/**
* Set the maximum number of bytes in the DeltaBaseCache.
*
* @param maxBytes
* the new limit.
* @return {@code this}
*/
public DhtReaderOptions setDeltaBaseCacheLimit(int maxBytes) {
deltaBaseCacheLimit = Math.max(0, maxBytes);
return this;
}
/** @return number of objects to cache information on. */
public int getRecentInfoCacheSize() {
return recentInfoCacheSize;
}
/**
* Set the number of objects to cache information on.
*
* @param objectCnt
* the number of objects to cache.
* @return {@code this}
*/
public DhtReaderOptions setRecentInfoCacheSize(int objectCnt) {
recentInfoCacheSize = Math.max(0, objectCnt);
return this;
}
/** @return number of recent chunks to hold onto per-reader. */
public int getRecentChunkCacheSize() {
return recentChunkCacheSize;
}
/**
* Set the number of chunks each reader holds onto for recently used access.
*
* @param chunkCnt
* the number of chunks each reader retains of recently used
* chunks to smooth out access.
* @return {@code this}
*/
public DhtReaderOptions setRecentChunkCacheSize(int chunkCnt) {
recentChunkCacheSize = Math.max(0, chunkCnt);
return this;
}
/**
* @return true if {@link DhtReader.Statistics} includes the stack trace for
* the first time a chunk is loaded. Supports debugging DHT code.
*/
public boolean isTrackFirstChunkLoad() {
return trackFirstChunkLoad;
}
/**
* Set whether or not the initial load of each chunk should be tracked.
*
* @param track
* true to track the stack trace of the first load.
* @return {@code this}.
*/
public DhtReaderOptions setTrackFirstChunkLoad(boolean track) {
trackFirstChunkLoad = track;
return this;
}
/**
* Update properties by setting fields from the configuration.
* <p>
* If a property is not defined in the configuration, then it is left
* unmodified.
*
* @param rc
* configuration to read properties from.
* @return {@code this}
*/
public DhtReaderOptions fromConfig(Config rc) {
setTimeout(Timeout.getTimeout(rc, "core", "dht", "timeout", getTimeout()));
setPrefetchFollowEdgeHints(rc.getBoolean("core", "dht", "prefetchFollowEdgeHints", isPrefetchFollowEdgeHints()));
setPrefetchLimit(rc.getInt("core", "dht", "prefetchLimit", getPrefetchLimit()));
setObjectIndexConcurrentBatches(rc.getInt("core", "dht", "objectIndexConcurrentBatches", getObjectIndexConcurrentBatches()));
setObjectIndexBatchSize(rc.getInt("core", "dht", "objectIndexBatchSize", getObjectIndexBatchSize()));
setDeltaBaseCacheSize(rc.getInt("core", "dht", "deltaBaseCacheSize", getDeltaBaseCacheSize()));
setDeltaBaseCacheLimit(rc.getInt("core", "dht", "deltaBaseCacheLimit", getDeltaBaseCacheLimit()));
setRecentInfoCacheSize(rc.getInt("core", "dht", "recentInfoCacheSize", getRecentInfoCacheSize()));
setRecentChunkCacheSize(rc.getInt("core", "dht", "recentChunkCacheSize", getRecentChunkCacheSize()));
setTrackFirstChunkLoad(rc.getBoolean("core", "dht", "debugTrackFirstChunkLoad", isTrackFirstChunkLoad()));
return this;
}
}