Author: mreutegg
Date: Tue Dec 5 12:41:23 2017
New Revision: 1817183
URL: http://svn.apache.org/viewvc?rev=1817183&view=rev
Log:
OAK-7023: Replacement for DocumentMK.Builder
Added:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java
(with props)
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilder.java
(with props)
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java
(with props)
Modified:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/TieredDiffCache.java
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
Modified:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java?rev=1817183&r1=1817182&r2=1817183&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
(original)
+++
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
Tue Dec 5 12:41:23 2017
@@ -24,13 +24,13 @@ import org.osgi.service.metatype.annotat
import org.osgi.service.metatype.annotations.Option;
import static org.apache.jackrabbit.oak.plugins.document.Configuration.PID;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_CACHE_SEGMENT_COUNT;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_CACHE_STACK_MOVE_DISTANCE;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_CHILDREN_CACHE_PERCENTAGE;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_DIFF_CACHE_PERCENTAGE;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_NODE_CACHE_PERCENTAGE;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_PREV_DOC_CACHE_PERCENTAGE;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_UPDATE_LIMIT;
+import static
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_CACHE_SEGMENT_COUNT;
+import static
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_CACHE_STACK_MOVE_DISTANCE;
+import static
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_CHILDREN_CACHE_PERCENTAGE;
+import static
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_DIFF_CACHE_PERCENTAGE;
+import static
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_NODE_CACHE_PERCENTAGE;
+import static
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_PREV_DOC_CACHE_PERCENTAGE;
+import static
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_UPDATE_LIMIT;
@ObjectClassDefinition(
pid = {PID},
Modified:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java?rev=1817183&r1=1817182&r2=1817183&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
(original)
+++
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
Tue Dec 5 12:41:23 2017
@@ -16,137 +16,60 @@
*/
package org.apache.jackrabbit.oak.plugins.document;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Suppliers.memoize;
import static com.google.common.base.Suppliers.ofInstance;
import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreServiceConfiguration.PROP_UPDATE_LIMIT;
-import static
org.apache.jackrabbit.oak.plugins.document.util.MongoConnection.readConcernLevel;
import java.io.InputStream;
-import java.net.UnknownHostException;
-import java.util.EnumMap;
-import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.sql.DataSource;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.base.Supplier;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.RemovalCause;
-import com.google.common.cache.RemovalListener;
-import com.google.common.cache.RemovalNotification;
-import com.google.common.cache.Weigher;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.mongodb.DB;
-import com.mongodb.MongoClientOptions;
-import com.mongodb.ReadConcernLevel;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.cache.CacheLIRS;
-import org.apache.jackrabbit.oak.cache.CacheLIRS.EvictionCallback;
-import org.apache.jackrabbit.oak.cache.CacheStats;
-import org.apache.jackrabbit.oak.cache.CacheValue;
-import org.apache.jackrabbit.oak.cache.EmpiricalWeigher;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.commons.json.JsopReader;
import org.apache.jackrabbit.oak.commons.json.JsopStream;
import org.apache.jackrabbit.oak.commons.json.JsopTokenizer;
import org.apache.jackrabbit.oak.commons.json.JsopWriter;
import org.apache.jackrabbit.oak.json.JsopDiff;
-import org.apache.jackrabbit.oak.plugins.blob.BlobStoreStats;
-import org.apache.jackrabbit.oak.plugins.blob.CachingBlobStore;
import org.apache.jackrabbit.oak.plugins.blob.ReferencedBlob;
import org.apache.jackrabbit.oak.plugins.document.DocumentNodeState.Children;
-import org.apache.jackrabbit.oak.plugins.document.cache.NodeDocumentCache;
-import org.apache.jackrabbit.oak.plugins.document.locks.NodeDocumentLocks;
-import org.apache.jackrabbit.oak.plugins.document.memory.MemoryDocumentStore;
-import
org.apache.jackrabbit.oak.plugins.document.mongo.MongoBlobReferenceIterator;
-import org.apache.jackrabbit.oak.plugins.document.mongo.MongoBlobStore;
-import org.apache.jackrabbit.oak.plugins.document.mongo.MongoDocumentStore;
-import
org.apache.jackrabbit.oak.plugins.document.mongo.MongoMissingLastRevSeeker;
-import org.apache.jackrabbit.oak.plugins.document.mongo.MongoVersionGCSupport;
-import org.apache.jackrabbit.oak.plugins.document.persistentCache.CacheType;
-import
org.apache.jackrabbit.oak.plugins.document.persistentCache.EvictionListener;
-import
org.apache.jackrabbit.oak.plugins.document.persistentCache.PersistentCache;
-import
org.apache.jackrabbit.oak.plugins.document.persistentCache.PersistentCacheStats;
+import
org.apache.jackrabbit.oak.plugins.document.mongo.MongoDocumentNodeStoreBuilder;
import org.apache.jackrabbit.oak.plugins.document.rdb.RDBBlobReferenceIterator;
import org.apache.jackrabbit.oak.plugins.document.rdb.RDBBlobStore;
+import
org.apache.jackrabbit.oak.plugins.document.rdb.RDBDocumentNodeStoreBuilder;
import org.apache.jackrabbit.oak.plugins.document.rdb.RDBDocumentStore;
import org.apache.jackrabbit.oak.plugins.document.rdb.RDBOptions;
import org.apache.jackrabbit.oak.plugins.document.rdb.RDBVersionGCSupport;
-import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
-import org.apache.jackrabbit.oak.plugins.document.mongo.MongoStatus;
-import org.apache.jackrabbit.oak.plugins.document.util.RevisionsKey;
-import org.apache.jackrabbit.oak.plugins.document.util.StringValue;
-import org.apache.jackrabbit.oak.spi.blob.AbstractBlobStore;
-import org.apache.jackrabbit.oak.spi.blob.BlobStore;
import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore;
-import org.apache.jackrabbit.oak.spi.blob.MemoryBlobStore;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
-import org.apache.jackrabbit.oak.spi.gc.GCMonitor;
-import org.apache.jackrabbit.oak.spi.gc.LoggingGCMonitor;
-import org.apache.jackrabbit.oak.stats.Clock;
-import org.apache.jackrabbit.oak.stats.StatisticsProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A JSON-based wrapper around the NodeStore implementation that stores the
* data in a {@link DocumentStore}. It is used for testing purpose only.
+ * @deprecated Use {@link DocumentNodeStore} instead.
*/
+@Deprecated
public class DocumentMK {
static final Logger LOG = LoggerFactory.getLogger(DocumentMK.class);
/**
- * The path where the persistent cache is stored.
- */
- static final String DEFAULT_PERSISTENT_CACHE_URI =
- System.getProperty("oak.documentMK.persCache");
-
- /**
* The threshold where special handling for many child node starts.
*/
- static final int MANY_CHILDREN_THRESHOLD = Integer.getInteger(
- "oak.documentMK.manyChildren", 50);
-
- /**
- * Enable or disable the LIRS cache (null to use the default setting for
this configuration).
- */
- static final Boolean LIRS_CACHE;
-
- static {
- String s = System.getProperty("oak.documentMK.lirsCache");
- LIRS_CACHE = s == null ? null : Boolean.parseBoolean(s);
- }
-
- /**
- * Enable fast diff operations.
- */
- static final boolean FAST_DIFF = Boolean.parseBoolean(
- System.getProperty("oak.documentMK.fastDiff", "true"));
-
+ static final int MANY_CHILDREN_THRESHOLD =
DocumentNodeStoreBuilder.MANY_CHILDREN_THRESHOLD;
/**
* Number of content updates that need to happen before the updates
* are automatically purged to the private branch.
*/
- static final int UPDATE_LIMIT = Integer.getInteger("update.limit",
Builder.DEFAULT_UPDATE_LIMIT);
+ static final int UPDATE_LIMIT = DocumentNodeStoreBuilder.UPDATE_LIMIT;
/**
* The node store.
@@ -553,201 +476,27 @@ public class DocumentMK {
/**
* A builder for a DocumentMK instance.
+ * @deprecated Use {@link DocumentNodeStoreBuilder} instead or one of the
+ * backend implementation specific variants {@link
MongoDocumentNodeStoreBuilder}
+ * or {@link RDBDocumentNodeStoreBuilder}.
+ *
*/
- public static class Builder {
- public static final long DEFAULT_MEMORY_CACHE_SIZE = 256 * 1024 * 1024;
- public static final int DEFAULT_NODE_CACHE_PERCENTAGE = 35;
- public static final int DEFAULT_PREV_DOC_CACHE_PERCENTAGE = 4;
- public static final int DEFAULT_CHILDREN_CACHE_PERCENTAGE = 15;
- public static final int DEFAULT_DIFF_CACHE_PERCENTAGE = 30;
- public static final int DEFAULT_CACHE_SEGMENT_COUNT = 16;
- public static final int DEFAULT_CACHE_STACK_MOVE_DISTANCE = 16;
- public static final int DEFAULT_UPDATE_LIMIT = 100000;
+ @Deprecated
+ public static class Builder extends
MongoDocumentNodeStoreBuilder<DocumentMK.Builder> {
+ public static final long DEFAULT_MEMORY_CACHE_SIZE =
DocumentNodeStoreBuilder.DEFAULT_MEMORY_CACHE_SIZE;
+ public static final int DEFAULT_NODE_CACHE_PERCENTAGE =
DocumentNodeStoreBuilder.DEFAULT_NODE_CACHE_PERCENTAGE;
+ public static final int DEFAULT_PREV_DOC_CACHE_PERCENTAGE =
DocumentNodeStoreBuilder.DEFAULT_PREV_DOC_CACHE_PERCENTAGE;
+ public static final int DEFAULT_CHILDREN_CACHE_PERCENTAGE =
DocumentNodeStoreBuilder.DEFAULT_CHILDREN_CACHE_PERCENTAGE;
+ public static final int DEFAULT_DIFF_CACHE_PERCENTAGE =
DocumentNodeStoreBuilder.DEFAULT_DIFF_CACHE_PERCENTAGE;
+ public static final int DEFAULT_CACHE_SEGMENT_COUNT =
DocumentNodeStoreBuilder.DEFAULT_CACHE_SEGMENT_COUNT;
+ public static final int DEFAULT_CACHE_STACK_MOVE_DISTANCE =
DocumentNodeStoreBuilder.DEFAULT_CACHE_STACK_MOVE_DISTANCE;
+ public static final int DEFAULT_UPDATE_LIMIT =
DocumentNodeStoreBuilder.DEFAULT_UPDATE_LIMIT;
private DocumentNodeStore nodeStore;
- private Supplier<DocumentStore> documentStoreSupplier = ofInstance(new
MemoryDocumentStore());
- private String mongoUri;
- private boolean socketKeepAlive;
- private MongoStatus mongoStatus;
- private DiffCache diffCache;
- private BlobStore blobStore;
- private int clusterId =
Integer.getInteger("oak.documentMK.clusterId", 0);
- private int asyncDelay = 1000;
- private boolean timing;
- private boolean logging;
- private boolean leaseCheck = true; // OAK-2739 is enabled by default
also for non-osgi
- private boolean isReadOnlyMode = false;
- private Weigher<CacheValue, CacheValue> weigher = new
EmpiricalWeigher();
- private long memoryCacheSize = DEFAULT_MEMORY_CACHE_SIZE;
- private int nodeCachePercentage = DEFAULT_NODE_CACHE_PERCENTAGE;
- private int prevDocCachePercentage = DEFAULT_PREV_DOC_CACHE_PERCENTAGE;
- private int childrenCachePercentage =
DEFAULT_CHILDREN_CACHE_PERCENTAGE;
- private int diffCachePercentage = DEFAULT_DIFF_CACHE_PERCENTAGE;
- private int cacheSegmentCount = DEFAULT_CACHE_SEGMENT_COUNT;
- private int cacheStackMoveDistance = DEFAULT_CACHE_STACK_MOVE_DISTANCE;
- private boolean useSimpleRevision;
- private long maxReplicationLagMillis = TimeUnit.HOURS.toMillis(6);
- private boolean disableBranches;
- private boolean prefetchExternalChanges;
- private Clock clock = Clock.SIMPLE;
- private Executor executor;
- private String persistentCacheURI = DEFAULT_PERSISTENT_CACHE_URI;
- private PersistentCache persistentCache;
- private String journalCacheURI;
- private PersistentCache journalCache;
- private LeaseFailureHandler leaseFailureHandler;
- private StatisticsProvider statisticsProvider =
StatisticsProvider.NOOP;
- private BlobStoreStats blobStoreStats;
- private CacheStats blobStoreCacheStats;
- private DocumentStoreStatsCollector documentStoreStatsCollector;
- private DocumentNodeStoreStatsCollector nodeStoreStatsCollector;
- private Map<CacheType, PersistentCacheStats> persistentCacheStats =
- new EnumMap<CacheType, PersistentCacheStats>(CacheType.class);
- private boolean bundlingDisabled;
- private JournalPropertyHandlerFactory journalPropertyHandlerFactory =
- new JournalPropertyHandlerFactory();
- private int updateLimit = UPDATE_LIMIT;
- private int commitValueCacheSize = 10000;
- private long maxRevisionAgeMillis = DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS;
- private GCMonitor gcMonitor = new LoggingGCMonitor(
- LoggerFactory.getLogger(VersionGarbageCollector.class));
- private Predicate<String> nodeCachePredicate = Predicates.alwaysTrue();
public Builder() {
}
/**
- * Uses the given information to connect to to MongoDB as backend
- * storage for the DocumentNodeStore. The write concern is either
- * taken from the URI or determined automatically based on the MongoDB
- * setup. When running on a replica set without explicit write concern
- * in the URI, the write concern will be {@code MAJORITY}, otherwise
- * {@code ACKNOWLEDGED}.
- *
- * @param uri a MongoDB URI.
- * @param name the name of the database to connect to. This overrides
- * any database name given in the {@code uri}.
- * @param blobCacheSizeMB the blob cache size in MB.
- * @return this
- * @throws UnknownHostException if one of the hosts given in the URI
- * is unknown.
- */
- public Builder setMongoDB(@Nonnull String uri,
- @Nonnull String name,
- int blobCacheSizeMB)
- throws UnknownHostException {
- this.mongoUri = uri;
-
- MongoClientOptions.Builder options =
MongoConnection.getDefaultBuilder();
- options.socketKeepAlive(socketKeepAlive);
- DB db = new MongoConnection(uri, options).getDB(name);
- MongoStatus status = new MongoStatus(db);
- if (!MongoConnection.hasWriteConcern(uri)) {
- db.setWriteConcern(MongoConnection.getDefaultWriteConcern(db));
- }
- if (status.isMajorityReadConcernSupported() &&
status.isMajorityReadConcernEnabled() && !MongoConnection.hasReadConcern(uri)) {
- db.setReadConcern(MongoConnection.getDefaultReadConcern(db));
- }
- setMongoDB(db, status, blobCacheSizeMB);
- return this;
- }
-
- /**
- * Use the given MongoDB as backend storage for the DocumentNodeStore.
- *
- * @param db the MongoDB connection
- * @return this
- */
- public Builder setMongoDB(@Nonnull DB db,
- int blobCacheSizeMB) {
- return setMongoDB(db, new MongoStatus(db), blobCacheSizeMB);
- }
-
- private Builder setMongoDB(@Nonnull DB db,
- MongoStatus status,
- int blobCacheSizeMB) {
- if (!MongoConnection.hasSufficientWriteConcern(db)) {
- LOG.warn("Insufficient write concern: " + db.getWriteConcern()
- + " At least " +
MongoConnection.getDefaultWriteConcern(db) + " is recommended.");
- }
- if (status.isMajorityReadConcernSupported() &&
!status.isMajorityReadConcernEnabled()) {
- LOG.warn("The read concern should be enabled on mongod using
--enableMajorityReadConcern");
- } else if (status.isMajorityReadConcernSupported() &&
!MongoConnection.hasSufficientReadConcern(db)) {
- ReadConcernLevel currentLevel =
readConcernLevel(db.getReadConcern());
- ReadConcernLevel recommendedLevel =
readConcernLevel(MongoConnection.getDefaultReadConcern(db));
- if (currentLevel == null) {
- LOG.warn("Read concern hasn't been set. At least " +
recommendedLevel + " is recommended.");
- } else {
- LOG.warn("Insufficient read concern: " + currentLevel + ".
At least " + recommendedLevel + " is recommended.");
- }
- }
-
- this.mongoStatus = status;
- this.documentStoreSupplier = memoize(new Supplier<DocumentStore>()
{
- @Override
- public DocumentStore get() {
- return new MongoDocumentStore(db, DocumentMK.Builder.this);
- }
- });
-
- if (this.blobStore == null) {
- GarbageCollectableBlobStore s = new MongoBlobStore(db,
blobCacheSizeMB * 1024 * 1024L);
- setBlobStore(s);
- }
- return this;
- }
-
- /**
- * Enables the socket keep-alive option for MongoDB. The default is
- * disabled.
- *
- * @param enable whether to enable it.
- * @return this
- */
- public Builder setSocketKeepAlive(boolean enable) {
- this.socketKeepAlive = enable;
- return this;
- }
-
- private void setBlobStore(GarbageCollectableBlobStore s) {
- configureBlobStore(s);
- PersistentCache p = getPersistentCache();
- if (p != null) {
- s = p.wrapBlobStore(s);
- }
- this.blobStore = s;
- }
-
- /**
- * Use the given MongoDB as backend storage for the DocumentNodeStore.
- *
- * @param db the MongoDB connection
- * @return this
- */
- public Builder setMongoDB(@Nonnull DB db) {
- return setMongoDB(db, 16);
- }
-
- /**
- * Returns the Mongo URI used in the {@link #setMongoDB(String,
String, int)} method.
- *
- * @return the Mongo URI or null if the {@link #setMongoDB(String,
String, int)} method hasn't
- * been called.
- */
- public String getMongoUri() {
- return mongoUri;
- }
-
- /**
- * Returns the status of the Mongo server configured in the {@link
#setMongoDB(String, String, int)} method.
- *
- * @return the status or null if the {@link #setMongoDB(String,
String, int)} method hasn't
- * been called.
- */
- public MongoStatus getMongoStatus() {
- return mongoStatus;
- }
-
- /**
* Sets a {@link DataSource} to use for the RDB document and blob
* stores.
*
@@ -768,7 +517,7 @@ public class DocumentMK {
this.documentStoreSupplier = ofInstance(new RDBDocumentStore(ds,
this, options));
if(blobStore == null) {
GarbageCollectableBlobStore s = new RDBBlobStore(ds, options);
- setBlobStore(s);
+ setGCBlobStore(s);
}
return this;
}
@@ -783,434 +532,33 @@ public class DocumentMK {
this.documentStoreSupplier = ofInstance(new
RDBDocumentStore(documentStoreDataSource, this));
if(blobStore == null) {
GarbageCollectableBlobStore s = new
RDBBlobStore(blobStoreDataSource);
- setBlobStore(s);
+ setGCBlobStore(s);
}
return this;
}
- /**
- * Sets the persistent cache option.
- *
- * @return this
- */
- public Builder setPersistentCache(String persistentCache) {
- this.persistentCacheURI = persistentCache;
- return this;
- }
-
- /**
- * Sets the journal cache option.
- *
- * @return this
- */
- public Builder setJournalCache(String journalCache) {
- this.journalCacheURI = journalCache;
- return this;
- }
-
- /**
- * Use the timing document store wrapper.
- *
- * @param timing whether to use the timing wrapper.
- * @return this
- */
- public Builder setTiming(boolean timing) {
- this.timing = timing;
- return this;
- }
-
- public boolean getTiming() {
- return timing;
- }
-
- public Builder setLogging(boolean logging) {
- this.logging = logging;
- return this;
- }
-
- public boolean getLogging() {
- return logging;
- }
-
- public Builder setLeaseCheck(boolean leaseCheck) {
- this.leaseCheck = leaseCheck;
- return this;
- }
-
- public boolean getLeaseCheck() {
- return leaseCheck;
- }
-
- public Builder setReadOnlyMode() {
- this.isReadOnlyMode = true;
- return this;
- }
-
- public boolean getReadOnlyMode() {
- return isReadOnlyMode;
- }
-
- public Builder setLeaseFailureHandler(LeaseFailureHandler
leaseFailureHandler) {
- this.leaseFailureHandler = leaseFailureHandler;
- return this;
- }
-
- public LeaseFailureHandler getLeaseFailureHandler() {
- return leaseFailureHandler;
- }
-
- /**
- * Set the document store to use. By default an in-memory store is
used.
- *
- * @param documentStore the document store
- * @return this
- */
- public Builder setDocumentStore(DocumentStore documentStore) {
- this.documentStoreSupplier = ofInstance(documentStore);
- return this;
- }
-
- public DocumentStore getDocumentStore() {
- return documentStoreSupplier.get();
- }
-
public DocumentNodeStore getNodeStore() {
if (nodeStore == null) {
- nodeStore = new DocumentNodeStore(this);
+ nodeStore = build();
}
return nodeStore;
}
- public DiffCache getDiffCache() {
- if (diffCache == null) {
- diffCache = new TieredDiffCache(this);
- }
- return diffCache;
- }
-
- public Builder setDiffCache(DiffCache diffCache) {
- this.diffCache = diffCache;
- return this;
- }
-
- /**
- * Set the blob store to use. By default an in-memory store is used.
- *
- * @param blobStore the blob store
- * @return this
- */
- public Builder setBlobStore(BlobStore blobStore) {
- this.blobStore = blobStore;
- return this;
- }
-
- public BlobStore getBlobStore() {
- if (blobStore == null) {
- blobStore = new MemoryBlobStore();
- configureBlobStore(blobStore);
- }
- return blobStore;
- }
-
- /**
- * Set the cluster id to use. By default, 0 is used, meaning the
cluster
- * id is automatically generated.
- *
- * @param clusterId the cluster id
- * @return this
- */
- public Builder setClusterId(int clusterId) {
- this.clusterId = clusterId;
- return this;
- }
-
- public Builder setCacheSegmentCount(int cacheSegmentCount) {
- this.cacheSegmentCount = cacheSegmentCount;
- return this;
- }
-
- public Builder setCacheStackMoveDistance(int cacheSegmentCount) {
- this.cacheStackMoveDistance = cacheSegmentCount;
- return this;
- }
-
- public int getClusterId() {
- return clusterId;
- }
-
- /**
- * Set the maximum delay to write the last revision to the root node.
By
- * default 1000 (meaning 1 second) is used.
- *
- * @param asyncDelay in milliseconds
- * @return this
- */
- public Builder setAsyncDelay(int asyncDelay) {
- this.asyncDelay = asyncDelay;
- return this;
- }
-
- public int getAsyncDelay() {
- return asyncDelay;
- }
-
- public Weigher<CacheValue, CacheValue> getWeigher() {
- return weigher;
- }
-
- public Builder withWeigher(Weigher<CacheValue, CacheValue> weigher) {
- this.weigher = weigher;
- return this;
- }
-
- public Builder memoryCacheSize(long memoryCacheSize) {
- this.memoryCacheSize = memoryCacheSize;
- return this;
- }
-
- public Builder memoryCacheDistribution(int nodeCachePercentage,
- int prevDocCachePercentage,
- int childrenCachePercentage,
- int diffCachePercentage) {
- checkArgument(nodeCachePercentage >= 0);
- checkArgument(prevDocCachePercentage >= 0);
- checkArgument(childrenCachePercentage>= 0);
- checkArgument(diffCachePercentage >= 0);
- checkArgument(nodeCachePercentage + prevDocCachePercentage +
childrenCachePercentage +
- diffCachePercentage < 100);
- this.nodeCachePercentage = nodeCachePercentage;
- this.prevDocCachePercentage = prevDocCachePercentage;
- this.childrenCachePercentage = childrenCachePercentage;
- this.diffCachePercentage = diffCachePercentage;
- return this;
- }
-
- public long getNodeCacheSize() {
- return memoryCacheSize * nodeCachePercentage / 100;
- }
-
- public long getPrevDocumentCacheSize() {
- return memoryCacheSize * prevDocCachePercentage / 100;
- }
-
- public long getChildrenCacheSize() {
- return memoryCacheSize * childrenCachePercentage / 100;
- }
-
- public long getDocumentCacheSize() {
- return memoryCacheSize - getNodeCacheSize() -
getPrevDocumentCacheSize() - getChildrenCacheSize()
- - getDiffCacheSize();
- }
-
- public long getDiffCacheSize() {
- return memoryCacheSize * diffCachePercentage / 100;
- }
-
- public long getMemoryDiffCacheSize() {
- return getDiffCacheSize() / 2;
- }
-
- public long getLocalDiffCacheSize() {
- return getDiffCacheSize() / 2;
- }
-
- public Builder setUseSimpleRevision(boolean useSimpleRevision) {
- this.useSimpleRevision = useSimpleRevision;
- return this;
- }
-
- public boolean isUseSimpleRevision() {
- return useSimpleRevision;
- }
-
- public Executor getExecutor() {
- if(executor == null){
- return MoreExecutors.sameThreadExecutor();
- }
- return executor;
- }
-
- public Builder setExecutor(Executor executor){
- this.executor = executor;
- return this;
- }
-
- public Builder clock(Clock clock) {
- this.clock = clock;
- return this;
- }
-
- public Builder setStatisticsProvider(StatisticsProvider
statisticsProvider){
- this.statisticsProvider = statisticsProvider;
- return this;
- }
-
- public StatisticsProvider getStatisticsProvider() {
- return this.statisticsProvider;
- }
- public DocumentStoreStatsCollector getDocumentStoreStatsCollector() {
- if (documentStoreStatsCollector == null) {
- documentStoreStatsCollector = new
DocumentStoreStats(statisticsProvider);
- }
- return documentStoreStatsCollector;
- }
-
- public Builder
setDocumentStoreStatsCollector(DocumentStoreStatsCollector
documentStoreStatsCollector) {
- this.documentStoreStatsCollector = documentStoreStatsCollector;
- return this;
- }
-
- public DocumentNodeStoreStatsCollector getNodeStoreStatsCollector() {
- if (nodeStoreStatsCollector == null) {
- nodeStoreStatsCollector = new
DocumentNodeStoreStats(statisticsProvider);
- }
- return nodeStoreStatsCollector;
- }
-
- public Builder
setNodeStoreStatsCollector(DocumentNodeStoreStatsCollector statsCollector) {
- this.nodeStoreStatsCollector = statsCollector;
- return this;
- }
-
- @Nonnull
- public Map<CacheType, PersistentCacheStats> getPersistenceCacheStats()
{
- return persistentCacheStats;
- }
-
- @CheckForNull
- public BlobStoreStats getBlobStoreStats() {
- return blobStoreStats;
- }
-
- @CheckForNull
- public CacheStats getBlobStoreCacheStats() {
- return blobStoreCacheStats;
- }
-
- public Clock getClock() {
- return clock;
- }
-
- public Builder setMaxReplicationLag(long duration, TimeUnit unit){
- maxReplicationLagMillis = unit.toMillis(duration);
- return this;
- }
-
- public long getMaxReplicationLagMillis() {
- return maxReplicationLagMillis;
- }
-
- public Builder disableBranches() {
- disableBranches = true;
- return this;
- }
-
- public boolean isDisableBranches() {
- return disableBranches;
- }
-
- public Builder setBundlingDisabled(boolean enabled) {
- bundlingDisabled = enabled;
- return this;
- }
-
- public boolean isBundlingDisabled() {
- return bundlingDisabled;
- }
-
- public Builder setPrefetchExternalChanges(boolean b) {
- prefetchExternalChanges = b;
- return this;
- }
-
- public boolean isPrefetchExternalChanges() {
- return prefetchExternalChanges;
- }
-
- public Builder
setJournalPropertyHandlerFactory(JournalPropertyHandlerFactory factory) {
- journalPropertyHandlerFactory = factory;
- return this;
- }
-
- public JournalPropertyHandlerFactory
getJournalPropertyHandlerFactory() {
- return journalPropertyHandlerFactory;
- }
-
- public Builder setUpdateLimit(int limit) {
- updateLimit = limit;
- return this;
- }
-
- public int getUpdateLimit() {
- return updateLimit;
- }
-
- public Builder setCommitValueCacheSize(int cacheSize) {
- this.commitValueCacheSize = cacheSize;
- return this;
- }
-
- public int getCommitValueCacheSize() {
- return commitValueCacheSize;
- }
-
- public Builder setJournalGCMaxAge(long maxRevisionAgeMillis) {
- this.maxRevisionAgeMillis = maxRevisionAgeMillis;
- return this;
- }
-
- /**
- * The maximum age for journal entries in milliseconds. Older entries
- * are candidates for GC.
- *
- * @return maximum age for journal entries in milliseconds.
- */
- public long getJournalGCMaxAge() {
- return maxRevisionAgeMillis;
- }
-
- public Builder setGCMonitor(@Nonnull GCMonitor gcMonitor) {
- this.gcMonitor = checkNotNull(gcMonitor);
- return this;
- }
-
- public GCMonitor getGCMonitor() {
- return gcMonitor;
- }
-
- VersionGCSupport createVersionGCSupport() {
+ public VersionGCSupport createVersionGCSupport() {
DocumentStore store = getDocumentStore();
- if (store instanceof MongoDocumentStore) {
- return new MongoVersionGCSupport((MongoDocumentStore) store);
- } else if (store instanceof RDBDocumentStore) {
+ if (store instanceof RDBDocumentStore) {
return new RDBVersionGCSupport((RDBDocumentStore) store);
} else {
- return new VersionGCSupport(store);
+ return super.createVersionGCSupport();
}
}
- Iterable<ReferencedBlob> createReferencedBlobs(final DocumentNodeStore
ns) {
+ public Iterable<ReferencedBlob>
createReferencedBlobs(DocumentNodeStore ns) {
final DocumentStore store = getDocumentStore();
- return new Iterable<ReferencedBlob>() {
- @Override
- public Iterator<ReferencedBlob> iterator() {
- if (store instanceof MongoDocumentStore) {
- return new MongoBlobReferenceIterator(ns,
(MongoDocumentStore) store);
- } else if (store instanceof RDBDocumentStore) {
- return new RDBBlobReferenceIterator(ns,
(RDBDocumentStore) store);
- } else {
- return new BlobReferenceIterator(ns);
- }
- }
- };
- }
-
- public MissingLastRevSeeker createMissingLastRevSeeker() {
- final DocumentStore store = getDocumentStore();
- if (store instanceof MongoDocumentStore) {
- return new MongoMissingLastRevSeeker((MongoDocumentStore)
store, getClock());
+ if (store instanceof RDBDocumentStore) {
+ return () -> new RDBBlobReferenceIterator(ns,
(RDBDocumentStore) store);
} else {
- return new MissingLastRevSeeker(store, getClock());
+ return super.createReferencedBlobs(ns);
}
}
@@ -1222,181 +570,5 @@ public class DocumentMK {
public DocumentMK open() {
return new DocumentMK(this);
}
-
- public Cache<PathRev, DocumentNodeState>
buildNodeCache(DocumentNodeStore store) {
- return buildCache(CacheType.NODE, getNodeCacheSize(), store, null);
- }
-
- public Cache<PathRev, DocumentNodeState.Children>
buildChildrenCache(DocumentNodeStore store) {
- return buildCache(CacheType.CHILDREN, getChildrenCacheSize(),
store, null);
- }
-
- public Cache<PathRev, StringValue> buildMemoryDiffCache() {
- return buildCache(CacheType.DIFF, getMemoryDiffCacheSize(), null,
null);
- }
-
- public Cache<RevisionsKey, LocalDiffCache.Diff> buildLocalDiffCache() {
- return buildCache(CacheType.LOCAL_DIFF, getLocalDiffCacheSize(),
null, null);
- }
-
- public Cache<CacheValue, NodeDocument>
buildDocumentCache(DocumentStore docStore) {
- return buildCache(CacheType.DOCUMENT, getDocumentCacheSize(),
null, docStore);
- }
-
- public Cache<StringValue, NodeDocument>
buildPrevDocumentsCache(DocumentStore docStore) {
- return buildCache(CacheType.PREV_DOCUMENT,
getPrevDocumentCacheSize(), null, docStore);
- }
-
- public NodeDocumentCache buildNodeDocumentCache(DocumentStore
docStore, NodeDocumentLocks locks) {
- Cache<CacheValue, NodeDocument> nodeDocumentsCache =
buildDocumentCache(docStore);
- CacheStats nodeDocumentsCacheStats = new
CacheStats(nodeDocumentsCache, "Document-Documents", getWeigher(),
getDocumentCacheSize());
-
- Cache<StringValue, NodeDocument> prevDocumentsCache =
buildPrevDocumentsCache(docStore);
- CacheStats prevDocumentsCacheStats = new
CacheStats(prevDocumentsCache, "Document-PrevDocuments", getWeigher(),
getPrevDocumentCacheSize());
-
- return new NodeDocumentCache(nodeDocumentsCache,
nodeDocumentsCacheStats, prevDocumentsCache, prevDocumentsCacheStats, locks);
- }
-
- public Builder setNodeCachePredicate(Predicate<String> p){
- this.nodeCachePredicate = p;
- return this;
- }
-
- public Predicate<String> getNodeCachePredicate() {
- return nodeCachePredicate;
- }
-
- @SuppressWarnings("unchecked")
- private <K extends CacheValue, V extends CacheValue> Cache<K, V>
buildCache(
- CacheType cacheType,
- long maxWeight,
- DocumentNodeStore docNodeStore,
- DocumentStore docStore
- ) {
- Set<EvictionListener<K, V>> listeners = new
CopyOnWriteArraySet<EvictionListener<K,V>>();
- Cache<K, V> cache = buildCache(cacheType.name(), maxWeight,
listeners);
- PersistentCache p = null;
- if (cacheType == CacheType.DIFF || cacheType ==
CacheType.LOCAL_DIFF) {
- // use separate journal cache if configured
- p = getJournalCache();
- }
- if (p == null) {
- // otherwise fall back to single persistent cache
- p = getPersistentCache();
- }
- if (p != null) {
- cache = p.wrap(docNodeStore, docStore, cache, cacheType,
statisticsProvider);
- if (cache instanceof EvictionListener) {
- listeners.add((EvictionListener<K, V>) cache);
- }
- PersistentCacheStats stats =
PersistentCache.getPersistentCacheStats(cache);
- if (stats != null) {
- persistentCacheStats.put(cacheType, stats);
- }
- }
- return cache;
- }
-
- public PersistentCache getPersistentCache() {
- if (persistentCacheURI == null) {
- return null;
- }
- if (persistentCache == null) {
- try {
- persistentCache = new PersistentCache(persistentCacheURI);
- } catch (Throwable e) {
- LOG.warn("Persistent cache not available; please disable
the configuration", e);
- throw new IllegalArgumentException(e);
- }
- }
- return persistentCache;
- }
-
- PersistentCache getJournalCache() {
- if (journalCacheURI == null) {
- return null;
- }
- if (journalCache == null) {
- try {
- journalCache = new PersistentCache(journalCacheURI);
- } catch (Throwable e) {
- LOG.warn("Journal cache not available; please disable the
configuration", e);
- throw new IllegalArgumentException(e);
- }
- }
- return journalCache;
- }
-
- private <K extends CacheValue, V extends CacheValue> Cache<K, V>
buildCache(
- String module,
- long maxWeight,
- final Set<EvictionListener<K, V>> listeners) {
- // by default, use the LIRS cache when using the persistent cache,
- // but don't use it otherwise
- boolean useLirs = persistentCacheURI != null;
- // allow to override this by using the system property
- if (LIRS_CACHE != null) {
- useLirs = LIRS_CACHE;
- }
- // do not use LIRS cache when maxWeight is zero (OAK-6953)
- if (useLirs && maxWeight > 0) {
- return CacheLIRS.<K, V>newBuilder().
- module(module).
- weigher(new Weigher<K, V>() {
- @Override
- public int weigh(K key, V value) {
- return weigher.weigh(key, value);
- }
- }).
- averageWeight(2000).
- maximumWeight(maxWeight).
- segmentCount(cacheSegmentCount).
- stackMoveDistance(cacheStackMoveDistance).
- recordStats().
- evictionCallback(new EvictionCallback<K, V>() {
- @Override
- public void evicted(K key, V value, RemovalCause
cause) {
- for (EvictionListener<K, V> l : listeners) {
- l.evicted(key, value, cause);
- }
- }
- }).
- build();
- }
- return CacheBuilder.newBuilder().
- concurrencyLevel(cacheSegmentCount).
- weigher(weigher).
- maximumWeight(maxWeight).
- recordStats().
- removalListener(new RemovalListener<K, V>() {
- @Override
- public void onRemoval(RemovalNotification<K, V>
notification) {
- for (EvictionListener<K, V> l : listeners) {
- l.evicted(notification.getKey(),
notification.getValue(), notification.getCause());
- }
- }
- }).
- build();
- }
-
- /**
- * BlobStore which are created by builder might get wrapped.
- * So here we perform any configuration and also access any
- * service exposed by the store
- *
- * @param blobStore store to config
- */
- private void configureBlobStore(BlobStore blobStore) {
- if (blobStore instanceof AbstractBlobStore){
- this.blobStoreStats = new BlobStoreStats(statisticsProvider);
- ((AbstractBlobStore)
blobStore).setStatsCollector(blobStoreStats);
- }
-
- if (blobStore instanceof CachingBlobStore){
- blobStoreCacheStats = ((CachingBlobStore)
blobStore).getCacheStats();
- }
- }
-
}
-
}
Modified:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1817183&r1=1817182&r2=1817183&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
(original)
+++
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
Tue Dec 5 12:41:23 2017
@@ -32,8 +32,7 @@ import static org.apache.jackrabbit.oak.
import static
org.apache.jackrabbit.oak.plugins.document.Collection.CLUSTER_NODES;
import static org.apache.jackrabbit.oak.plugins.document.Collection.JOURNAL;
import static org.apache.jackrabbit.oak.plugins.document.Collection.NODES;
-import static org.apache.jackrabbit.oak.plugins.document.DocumentMK.FAST_DIFF;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.MANY_CHILDREN_THRESHOLD;
+import static
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.MANY_CHILDREN_THRESHOLD;
import static
org.apache.jackrabbit.oak.plugins.document.NodeDocument.MODIFIED_IN_SECS_RESOLUTION;
import static org.apache.jackrabbit.oak.plugins.document.UpdateOp.Key;
import static org.apache.jackrabbit.oak.plugins.document.UpdateOp.Operation;
@@ -159,6 +158,12 @@ public final class DocumentNodeStore
);
/**
+ * Enable fast diff operations.
+ */
+ private static final boolean FAST_DIFF = Boolean.parseBoolean(
+ System.getProperty("oak.documentMK.fastDiff", "true"));
+
+ /**
* Feature flag to enable concurrent add/remove operations of hidden empty
* nodes. See OAK-2673.
*/
@@ -507,7 +512,7 @@ public final class DocumentNodeStore
private final Predicate<String> nodeCachePredicate;
- public DocumentNodeStore(DocumentMK.Builder builder) {
+ public <T extends DocumentNodeStoreBuilder<T>>
DocumentNodeStore(DocumentNodeStoreBuilder<T> builder) {
this.nodeCachePredicate = builder.getNodeCachePredicate();
this.updateLimit = builder.getUpdateLimit();
this.commitValueResolver = new
CommitValueResolver(builder.getCommitValueCacheSize(),
@@ -2995,7 +3000,7 @@ public final class DocumentNodeStore
return mbean;
}
- private DocumentNodeStoreMBean createMBean(DocumentMK.Builder builder) {
+ private DocumentNodeStoreMBean createMBean(DocumentNodeStoreBuilder
builder) {
try {
return new DocumentNodeStoreMBeanImpl(this,
builder.getStatisticsProvider().getStats(),
Modified:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java?rev=1817183&r1=1817182&r2=1817183&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
(original)
+++
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
Tue Dec 5 12:41:23 2017
@@ -452,7 +452,7 @@ class DocumentNodeStoreBranch implements
* as the base of this branch</li>
* <li>{@link Persisted} on {@link #setRoot(NodeState)} if the number
of
* changes counted from the base to the new root reaches
- * {@link DocumentMK.Builder#getUpdateLimit()}.</li>
+ * {@link DocumentNodeStoreBuilder#getUpdateLimit()}.</li>
* <li>{@link Merged} on {@link BranchState#merge(CommitHook,
CommitInfo, boolean)}</li>
* </ul>
*/
Added:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java?rev=1817183&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java
(added)
+++
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java
Tue Dec 5 12:41:23 2017
@@ -0,0 +1,750 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.document;
+
+import java.util.EnumMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.Executor;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.RemovalCause;
+import com.google.common.cache.RemovalListener;
+import com.google.common.cache.RemovalNotification;
+import com.google.common.cache.Weigher;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import org.apache.jackrabbit.oak.cache.CacheLIRS;
+import org.apache.jackrabbit.oak.cache.CacheStats;
+import org.apache.jackrabbit.oak.cache.CacheValue;
+import org.apache.jackrabbit.oak.cache.EmpiricalWeigher;
+import org.apache.jackrabbit.oak.plugins.blob.BlobStoreStats;
+import org.apache.jackrabbit.oak.plugins.blob.CachingBlobStore;
+import org.apache.jackrabbit.oak.plugins.blob.ReferencedBlob;
+import org.apache.jackrabbit.oak.plugins.document.cache.NodeDocumentCache;
+import org.apache.jackrabbit.oak.plugins.document.locks.NodeDocumentLocks;
+import org.apache.jackrabbit.oak.plugins.document.memory.MemoryDocumentStore;
+import org.apache.jackrabbit.oak.plugins.document.persistentCache.CacheType;
+import
org.apache.jackrabbit.oak.plugins.document.persistentCache.EvictionListener;
+import
org.apache.jackrabbit.oak.plugins.document.persistentCache.PersistentCache;
+import
org.apache.jackrabbit.oak.plugins.document.persistentCache.PersistentCacheStats;
+import org.apache.jackrabbit.oak.plugins.document.util.RevisionsKey;
+import org.apache.jackrabbit.oak.plugins.document.util.StringValue;
+import org.apache.jackrabbit.oak.spi.blob.AbstractBlobStore;
+import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore;
+import org.apache.jackrabbit.oak.spi.blob.MemoryBlobStore;
+import org.apache.jackrabbit.oak.spi.gc.GCMonitor;
+import org.apache.jackrabbit.oak.spi.gc.LoggingGCMonitor;
+import org.apache.jackrabbit.oak.stats.Clock;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Suppliers.ofInstance;
+import static
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS;
+
+/**
+ * A generic builder for a {@link DocumentNodeStore}. By default the builder
+ * will create an in-memory {@link DocumentNodeStore}. In most cases this is
+ * only useful for tests.
+ */
+public class DocumentNodeStoreBuilder<T extends DocumentNodeStoreBuilder<T>> {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(DocumentNodeStoreBuilder.class);
+
+ public static final long DEFAULT_MEMORY_CACHE_SIZE = 256 * 1024 * 1024;
+ public static final int DEFAULT_NODE_CACHE_PERCENTAGE = 35;
+ public static final int DEFAULT_PREV_DOC_CACHE_PERCENTAGE = 4;
+ public static final int DEFAULT_CHILDREN_CACHE_PERCENTAGE = 15;
+ public static final int DEFAULT_DIFF_CACHE_PERCENTAGE = 30;
+ public static final int DEFAULT_CACHE_SEGMENT_COUNT = 16;
+ public static final int DEFAULT_CACHE_STACK_MOVE_DISTANCE = 16;
+ public static final int DEFAULT_UPDATE_LIMIT = 100000;
+
+ /**
+ * The path where the persistent cache is stored.
+ */
+ private static final String DEFAULT_PERSISTENT_CACHE_URI =
+ System.getProperty("oak.documentMK.persCache");
+
+ /**
+ * The threshold where special handling for many child node starts.
+ */
+ static final int MANY_CHILDREN_THRESHOLD = Integer.getInteger(
+ "oak.documentMK.manyChildren", 50);
+
+ /**
+ * Enable or disable the LIRS cache (null to use the default setting for
this configuration).
+ */
+ private static final Boolean LIRS_CACHE;
+
+ static {
+ String s = System.getProperty("oak.documentMK.lirsCache");
+ LIRS_CACHE = s == null ? null : Boolean.parseBoolean(s);
+ }
+
+ /**
+ * Enable fast diff operations.
+ */
+ static final boolean FAST_DIFF = Boolean.parseBoolean(
+ System.getProperty("oak.documentMK.fastDiff", "true"));
+
+ /**
+ * Number of content updates that need to happen before the updates
+ * are automatically purged to the private branch.
+ */
+ static final int UPDATE_LIMIT = Integer.getInteger("update.limit",
DEFAULT_UPDATE_LIMIT);
+
+ protected Supplier<DocumentStore> documentStoreSupplier = ofInstance(new
MemoryDocumentStore());
+ protected BlobStore blobStore;
+ private DiffCache diffCache;
+ private int clusterId = Integer.getInteger("oak.documentMK.clusterId", 0);
+ private int asyncDelay = 1000;
+ private boolean timing;
+ private boolean logging;
+ private boolean leaseCheck = true; // OAK-2739 is enabled by default also
for non-osgi
+ private boolean isReadOnlyMode = false;
+ private Weigher<CacheValue, CacheValue> weigher = new EmpiricalWeigher();
+ private long memoryCacheSize = DEFAULT_MEMORY_CACHE_SIZE;
+ private int nodeCachePercentage = DEFAULT_NODE_CACHE_PERCENTAGE;
+ private int prevDocCachePercentage = DEFAULT_PREV_DOC_CACHE_PERCENTAGE;
+ private int childrenCachePercentage = DEFAULT_CHILDREN_CACHE_PERCENTAGE;
+ private int diffCachePercentage = DEFAULT_DIFF_CACHE_PERCENTAGE;
+ private int cacheSegmentCount = DEFAULT_CACHE_SEGMENT_COUNT;
+ private int cacheStackMoveDistance = DEFAULT_CACHE_STACK_MOVE_DISTANCE;
+ private boolean useSimpleRevision;
+ private boolean disableBranches;
+ private boolean prefetchExternalChanges;
+ private Clock clock = Clock.SIMPLE;
+ private Executor executor;
+ private String persistentCacheURI = DEFAULT_PERSISTENT_CACHE_URI;
+ private PersistentCache persistentCache;
+ private String journalCacheURI;
+ private PersistentCache journalCache;
+ private LeaseFailureHandler leaseFailureHandler;
+ private StatisticsProvider statisticsProvider = StatisticsProvider.NOOP;
+ private BlobStoreStats blobStoreStats;
+ private CacheStats blobStoreCacheStats;
+ private DocumentStoreStatsCollector documentStoreStatsCollector;
+ private DocumentNodeStoreStatsCollector nodeStoreStatsCollector;
+ private Map<CacheType, PersistentCacheStats> persistentCacheStats =
+ new EnumMap<CacheType, PersistentCacheStats>(CacheType.class);
+ private boolean bundlingDisabled;
+ private JournalPropertyHandlerFactory journalPropertyHandlerFactory =
+ new JournalPropertyHandlerFactory();
+ private int updateLimit = UPDATE_LIMIT;
+ private int commitValueCacheSize = 10000;
+ private long maxRevisionAgeMillis = DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS;
+ private GCMonitor gcMonitor = new LoggingGCMonitor(
+ LoggerFactory.getLogger(VersionGarbageCollector.class));
+ private Predicate<String> nodeCachePredicate = Predicates.alwaysTrue();
+
+ /**
+ * @return a new {@link DocumentNodeStoreBuilder}.
+ */
+ public static DocumentNodeStoreBuilder newDocumentNodeStoreBuilder() {
+ return new DocumentNodeStoreBuilder();
+ }
+
+ public DocumentNodeStore build() {
+ return new DocumentNodeStore(this);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected T thisBuilder() {
+ return (T) this;
+ }
+
+ /**
+ * Sets the persistent cache option.
+ *
+ * @return this
+ */
+ public T setPersistentCache(String persistentCache) {
+ this.persistentCacheURI = persistentCache;
+ return thisBuilder();
+ }
+
+ /**
+ * Sets the journal cache option.
+ *
+ * @return this
+ */
+ public T setJournalCache(String journalCache) {
+ this.journalCacheURI = journalCache;
+ return thisBuilder();
+ }
+
+ /**
+ * Use the timing document store wrapper.
+ *
+ * @param timing whether to use the timing wrapper.
+ * @return this
+ */
+ public T setTiming(boolean timing) {
+ this.timing = timing;
+ return thisBuilder();
+ }
+
+ public boolean getTiming() {
+ return timing;
+ }
+
+ public T setLogging(boolean logging) {
+ this.logging = logging;
+ return thisBuilder();
+ }
+
+ public boolean getLogging() {
+ return logging;
+ }
+
+ public T setLeaseCheck(boolean leaseCheck) {
+ this.leaseCheck = leaseCheck;
+ return thisBuilder();
+ }
+
+ public boolean getLeaseCheck() {
+ return leaseCheck;
+ }
+
+ public T setReadOnlyMode() {
+ this.isReadOnlyMode = true;
+ return thisBuilder();
+ }
+
+ public boolean getReadOnlyMode() {
+ return isReadOnlyMode;
+ }
+
+ public T setLeaseFailureHandler(LeaseFailureHandler leaseFailureHandler) {
+ this.leaseFailureHandler = leaseFailureHandler;
+ return thisBuilder();
+ }
+
+ public LeaseFailureHandler getLeaseFailureHandler() {
+ return leaseFailureHandler;
+ }
+
+ /**
+ * Set the document store to use. By default an in-memory store is used.
+ *
+ * @param documentStore the document store
+ * @return this
+ */
+ public T setDocumentStore(DocumentStore documentStore) {
+ this.documentStoreSupplier = ofInstance(documentStore);
+ return thisBuilder();
+ }
+
+ public DocumentStore getDocumentStore() {
+ return documentStoreSupplier.get();
+ }
+
+ public DiffCache getDiffCache() {
+ if (diffCache == null) {
+ diffCache = new TieredDiffCache(this);
+ }
+ return diffCache;
+ }
+
+ public T setDiffCache(DiffCache diffCache) {
+ this.diffCache = diffCache;
+ return thisBuilder();
+ }
+
+ /**
+ * Set the blob store to use. By default an in-memory store is used.
+ *
+ * @param blobStore the blob store
+ * @return this
+ */
+ public T setBlobStore(BlobStore blobStore) {
+ this.blobStore = blobStore;
+ return thisBuilder();
+ }
+
+ public BlobStore getBlobStore() {
+ if (blobStore == null) {
+ blobStore = new MemoryBlobStore();
+ configureBlobStore(blobStore);
+ }
+ return blobStore;
+ }
+
+ /**
+ * Set the cluster id to use. By default, 0 is used, meaning the cluster
+ * id is automatically generated.
+ *
+ * @param clusterId the cluster id
+ * @return this
+ */
+ public T setClusterId(int clusterId) {
+ this.clusterId = clusterId;
+ return thisBuilder();
+ }
+
+ public T setCacheSegmentCount(int cacheSegmentCount) {
+ this.cacheSegmentCount = cacheSegmentCount;
+ return thisBuilder();
+ }
+
+ public T setCacheStackMoveDistance(int cacheSegmentCount) {
+ this.cacheStackMoveDistance = cacheSegmentCount;
+ return thisBuilder();
+ }
+
+ public int getClusterId() {
+ return clusterId;
+ }
+
+ /**
+ * Set the maximum delay to write the last revision to the root node. By
+ * default 1000 (meaning 1 second) is used.
+ *
+ * @param asyncDelay in milliseconds
+ * @return this
+ */
+ public T setAsyncDelay(int asyncDelay) {
+ this.asyncDelay = asyncDelay;
+ return thisBuilder();
+ }
+
+ public int getAsyncDelay() {
+ return asyncDelay;
+ }
+
+ public Weigher<CacheValue, CacheValue> getWeigher() {
+ return weigher;
+ }
+
+ public T withWeigher(Weigher<CacheValue, CacheValue> weigher) {
+ this.weigher = weigher;
+ return thisBuilder();
+ }
+
+ public T memoryCacheSize(long memoryCacheSize) {
+ this.memoryCacheSize = memoryCacheSize;
+ return thisBuilder();
+ }
+
+ public T memoryCacheDistribution(int nodeCachePercentage,
+ int prevDocCachePercentage,
+ int childrenCachePercentage,
+ int diffCachePercentage) {
+ checkArgument(nodeCachePercentage >= 0);
+ checkArgument(prevDocCachePercentage >= 0);
+ checkArgument(childrenCachePercentage>= 0);
+ checkArgument(diffCachePercentage >= 0);
+ checkArgument(nodeCachePercentage + prevDocCachePercentage +
childrenCachePercentage +
+ diffCachePercentage < 100);
+ this.nodeCachePercentage = nodeCachePercentage;
+ this.prevDocCachePercentage = prevDocCachePercentage;
+ this.childrenCachePercentage = childrenCachePercentage;
+ this.diffCachePercentage = diffCachePercentage;
+ return thisBuilder();
+ }
+
+ public long getNodeCacheSize() {
+ return memoryCacheSize * nodeCachePercentage / 100;
+ }
+
+ public long getPrevDocumentCacheSize() {
+ return memoryCacheSize * prevDocCachePercentage / 100;
+ }
+
+ public long getChildrenCacheSize() {
+ return memoryCacheSize * childrenCachePercentage / 100;
+ }
+
+ public long getDocumentCacheSize() {
+ return memoryCacheSize - getNodeCacheSize() -
getPrevDocumentCacheSize() - getChildrenCacheSize()
+ - getDiffCacheSize();
+ }
+
+ public long getDiffCacheSize() {
+ return memoryCacheSize * diffCachePercentage / 100;
+ }
+
+ public long getMemoryDiffCacheSize() {
+ return getDiffCacheSize() / 2;
+ }
+
+ public long getLocalDiffCacheSize() {
+ return getDiffCacheSize() / 2;
+ }
+
+ public T setUseSimpleRevision(boolean useSimpleRevision) {
+ this.useSimpleRevision = useSimpleRevision;
+ return thisBuilder();
+ }
+
+ public boolean isUseSimpleRevision() {
+ return useSimpleRevision;
+ }
+
+ public Executor getExecutor() {
+ if(executor == null){
+ return MoreExecutors.sameThreadExecutor();
+ }
+ return executor;
+ }
+
+ public T setExecutor(Executor executor){
+ this.executor = executor;
+ return thisBuilder();
+ }
+
+ public T clock(Clock clock) {
+ this.clock = clock;
+ return thisBuilder();
+ }
+
+ public T setStatisticsProvider(StatisticsProvider statisticsProvider){
+ this.statisticsProvider = statisticsProvider;
+ return thisBuilder();
+ }
+
+ public StatisticsProvider getStatisticsProvider() {
+ return this.statisticsProvider;
+ }
+ public DocumentStoreStatsCollector getDocumentStoreStatsCollector() {
+ if (documentStoreStatsCollector == null) {
+ documentStoreStatsCollector = new
DocumentStoreStats(statisticsProvider);
+ }
+ return documentStoreStatsCollector;
+ }
+
+ public T setDocumentStoreStatsCollector(DocumentStoreStatsCollector
documentStoreStatsCollector) {
+ this.documentStoreStatsCollector = documentStoreStatsCollector;
+ return thisBuilder();
+ }
+
+ public DocumentNodeStoreStatsCollector getNodeStoreStatsCollector() {
+ if (nodeStoreStatsCollector == null) {
+ nodeStoreStatsCollector = new
DocumentNodeStoreStats(statisticsProvider);
+ }
+ return nodeStoreStatsCollector;
+ }
+
+ public T setNodeStoreStatsCollector(DocumentNodeStoreStatsCollector
statsCollector) {
+ this.nodeStoreStatsCollector = statsCollector;
+ return thisBuilder();
+ }
+
+ @Nonnull
+ public Map<CacheType, PersistentCacheStats> getPersistenceCacheStats() {
+ return persistentCacheStats;
+ }
+
+ @CheckForNull
+ public BlobStoreStats getBlobStoreStats() {
+ return blobStoreStats;
+ }
+
+ @CheckForNull
+ public CacheStats getBlobStoreCacheStats() {
+ return blobStoreCacheStats;
+ }
+
+ public Clock getClock() {
+ return clock;
+ }
+
+ public T disableBranches() {
+ disableBranches = true;
+ return thisBuilder();
+ }
+
+ public boolean isDisableBranches() {
+ return disableBranches;
+ }
+
+ public T setBundlingDisabled(boolean enabled) {
+ bundlingDisabled = enabled;
+ return thisBuilder();
+ }
+
+ public boolean isBundlingDisabled() {
+ return bundlingDisabled;
+ }
+
+ public T setPrefetchExternalChanges(boolean b) {
+ prefetchExternalChanges = b;
+ return thisBuilder();
+ }
+
+ public boolean isPrefetchExternalChanges() {
+ return prefetchExternalChanges;
+ }
+
+ public T setJournalPropertyHandlerFactory(JournalPropertyHandlerFactory
factory) {
+ journalPropertyHandlerFactory = factory;
+ return thisBuilder();
+ }
+
+ public JournalPropertyHandlerFactory getJournalPropertyHandlerFactory() {
+ return journalPropertyHandlerFactory;
+ }
+
+ public T setUpdateLimit(int limit) {
+ updateLimit = limit;
+ return thisBuilder();
+ }
+
+ public int getUpdateLimit() {
+ return updateLimit;
+ }
+
+ public T setCommitValueCacheSize(int cacheSize) {
+ this.commitValueCacheSize = cacheSize;
+ return thisBuilder();
+ }
+
+ public int getCommitValueCacheSize() {
+ return commitValueCacheSize;
+ }
+
+ public T setJournalGCMaxAge(long maxRevisionAgeMillis) {
+ this.maxRevisionAgeMillis = maxRevisionAgeMillis;
+ return thisBuilder();
+ }
+
+ /**
+ * The maximum age for journal entries in milliseconds. Older entries
+ * are candidates for GC.
+ *
+ * @return maximum age for journal entries in milliseconds.
+ */
+ public long getJournalGCMaxAge() {
+ return maxRevisionAgeMillis;
+ }
+
+ public T setGCMonitor(@Nonnull GCMonitor gcMonitor) {
+ this.gcMonitor = checkNotNull(gcMonitor);
+ return thisBuilder();
+ }
+
+ public GCMonitor getGCMonitor() {
+ return gcMonitor;
+ }
+
+ public VersionGCSupport createVersionGCSupport() {
+ return new VersionGCSupport(getDocumentStore());
+ }
+
+ public Iterable<ReferencedBlob> createReferencedBlobs(final
DocumentNodeStore ns) {
+ return () -> new BlobReferenceIterator(ns);
+ }
+
+ public MissingLastRevSeeker createMissingLastRevSeeker() {
+ return new MissingLastRevSeeker(getDocumentStore(), getClock());
+ }
+
+ public Cache<PathRev, DocumentNodeState> buildNodeCache(DocumentNodeStore
store) {
+ return buildCache(CacheType.NODE, getNodeCacheSize(), store, null);
+ }
+
+ public Cache<PathRev, DocumentNodeState.Children>
buildChildrenCache(DocumentNodeStore store) {
+ return buildCache(CacheType.CHILDREN, getChildrenCacheSize(), store,
null);
+ }
+
+ public Cache<PathRev, StringValue> buildMemoryDiffCache() {
+ return buildCache(CacheType.DIFF, getMemoryDiffCacheSize(), null,
null);
+ }
+
+ public Cache<RevisionsKey, LocalDiffCache.Diff> buildLocalDiffCache() {
+ return buildCache(CacheType.LOCAL_DIFF, getLocalDiffCacheSize(), null,
null);
+ }
+
+ public Cache<CacheValue, NodeDocument> buildDocumentCache(DocumentStore
docStore) {
+ return buildCache(CacheType.DOCUMENT, getDocumentCacheSize(), null,
docStore);
+ }
+
+ public Cache<StringValue, NodeDocument>
buildPrevDocumentsCache(DocumentStore docStore) {
+ return buildCache(CacheType.PREV_DOCUMENT, getPrevDocumentCacheSize(),
null, docStore);
+ }
+
+ public NodeDocumentCache buildNodeDocumentCache(DocumentStore docStore,
NodeDocumentLocks locks) {
+ Cache<CacheValue, NodeDocument> nodeDocumentsCache =
buildDocumentCache(docStore);
+ CacheStats nodeDocumentsCacheStats = new
CacheStats(nodeDocumentsCache, "Document-Documents", getWeigher(),
getDocumentCacheSize());
+
+ Cache<StringValue, NodeDocument> prevDocumentsCache =
buildPrevDocumentsCache(docStore);
+ CacheStats prevDocumentsCacheStats = new
CacheStats(prevDocumentsCache, "Document-PrevDocuments", getWeigher(),
getPrevDocumentCacheSize());
+
+ return new NodeDocumentCache(nodeDocumentsCache,
nodeDocumentsCacheStats, prevDocumentsCache, prevDocumentsCacheStats, locks);
+ }
+
+ public T setNodeCachePredicate(Predicate<String> p){
+ this.nodeCachePredicate = p;
+ return thisBuilder();
+ }
+
+ public Predicate<String> getNodeCachePredicate() {
+ return nodeCachePredicate;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <K extends CacheValue, V extends CacheValue> Cache<K, V>
buildCache(
+ CacheType cacheType,
+ long maxWeight,
+ DocumentNodeStore docNodeStore,
+ DocumentStore docStore) {
+ Set<EvictionListener<K, V>> listeners = new
CopyOnWriteArraySet<EvictionListener<K,V>>();
+ Cache<K, V> cache = buildCache(cacheType.name(), maxWeight, listeners);
+ PersistentCache p = null;
+ if (cacheType == CacheType.DIFF || cacheType == CacheType.LOCAL_DIFF) {
+ // use separate journal cache if configured
+ p = getJournalCache();
+ }
+ if (p == null) {
+ // otherwise fall back to single persistent cache
+ p = getPersistentCache();
+ }
+ if (p != null) {
+ cache = p.wrap(docNodeStore, docStore, cache, cacheType,
statisticsProvider);
+ if (cache instanceof EvictionListener) {
+ listeners.add((EvictionListener<K, V>) cache);
+ }
+ PersistentCacheStats stats =
PersistentCache.getPersistentCacheStats(cache);
+ if (stats != null) {
+ persistentCacheStats.put(cacheType, stats);
+ }
+ }
+ return cache;
+ }
+
+ public PersistentCache getPersistentCache() {
+ if (persistentCacheURI == null) {
+ return null;
+ }
+ if (persistentCache == null) {
+ try {
+ persistentCache = new PersistentCache(persistentCacheURI);
+ } catch (Throwable e) {
+ LOG.warn("Persistent cache not available; please disable the
configuration", e);
+ throw new IllegalArgumentException(e);
+ }
+ }
+ return persistentCache;
+ }
+
+ PersistentCache getJournalCache() {
+ if (journalCacheURI == null) {
+ return null;
+ }
+ if (journalCache == null) {
+ try {
+ journalCache = new PersistentCache(journalCacheURI);
+ } catch (Throwable e) {
+ LOG.warn("Journal cache not available; please disable the
configuration", e);
+ throw new IllegalArgumentException(e);
+ }
+ }
+ return journalCache;
+ }
+
+ private <K extends CacheValue, V extends CacheValue> Cache<K, V>
buildCache(
+ String module,
+ long maxWeight,
+ final Set<EvictionListener<K, V>> listeners) {
+ // by default, use the LIRS cache when using the persistent cache,
+ // but don't use it otherwise
+ boolean useLirs = persistentCacheURI != null;
+ // allow to override this by using the system property
+ if (LIRS_CACHE != null) {
+ useLirs = LIRS_CACHE;
+ }
+ // do not use LIRS cache when maxWeight is zero (OAK-6953)
+ if (useLirs && maxWeight > 0) {
+ return CacheLIRS.<K, V>newBuilder().
+ module(module).
+ weigher(new Weigher<K, V>() {
+ @Override
+ public int weigh(K key, V value) {
+ return weigher.weigh(key, value);
+ }
+ }).
+ averageWeight(2000).
+ maximumWeight(maxWeight).
+ segmentCount(cacheSegmentCount).
+ stackMoveDistance(cacheStackMoveDistance).
+ recordStats().
+ evictionCallback(new CacheLIRS.EvictionCallback<K, V>() {
+ @Override
+ public void evicted(K key, V value, RemovalCause
cause) {
+ for (EvictionListener<K, V> l : listeners) {
+ l.evicted(key, value, cause);
+ }
+ }
+ }).
+ build();
+ }
+ return CacheBuilder.newBuilder().
+ concurrencyLevel(cacheSegmentCount).
+ weigher(weigher).
+ maximumWeight(maxWeight).
+ recordStats().
+ removalListener(new RemovalListener<K, V>() {
+ @Override
+ public void onRemoval(RemovalNotification<K, V>
notification) {
+ for (EvictionListener<K, V> l : listeners) {
+ l.evicted(notification.getKey(),
notification.getValue(), notification.getCause());
+ }
+ }
+ }).
+ build();
+ }
+
+ protected void setGCBlobStore(GarbageCollectableBlobStore s) {
+ configureBlobStore(s);
+ PersistentCache p = getPersistentCache();
+ if (p != null) {
+ s = p.wrapBlobStore(s);
+ }
+ this.blobStore = s;
+ }
+
+ /**
+ * BlobStore which are created by builder might get wrapped.
+ * So here we perform any configuration and also access any
+ * service exposed by the store
+ *
+ * @param blobStore store to config
+ */
+ private void configureBlobStore(BlobStore blobStore) {
+ if (blobStore instanceof AbstractBlobStore){
+ this.blobStoreStats = new BlobStoreStats(statisticsProvider);
+ ((AbstractBlobStore) blobStore).setStatsCollector(blobStoreStats);
+ }
+
+ if (blobStore instanceof CachingBlobStore){
+ blobStoreCacheStats = ((CachingBlobStore)
blobStore).getCacheStats();
+ }
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native