diff --git oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java index 7274cc7..2af7074 100644 --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java @@ -89,6 +89,8 @@ public class SegmentNodeStore implements NodeStore, Observable { private boolean isCreated; + private boolean dispatchChanges = true; + private SegmentNodeStoreBuilder( @Nonnull Revisions revisions, @Nonnull SegmentReader reader, @@ -101,6 +103,12 @@ public class SegmentNodeStore implements NodeStore, Observable { } @Nonnull + public SegmentNodeStoreBuilder dispatchChanges(boolean dispatchChanges) { + this.dispatchChanges = dispatchChanges; + return this; + } + + @Nonnull public SegmentNodeStore build() { checkState(!isCreated); isCreated = true; @@ -188,7 +196,9 @@ public class SegmentNodeStore implements NodeStore, Observable { this.writer = builder.writer; this.blobStore = builder.blobStore; this.head = new AtomicReference(reader.readHeadState(revisions)); - this.changeDispatcher = new ChangeDispatcher(getRoot()); + this.changeDispatcher = builder.dispatchChanges ? + new ChangeDispatcher(getRoot()) : + null; } void setMaximumBackoff(long max) { @@ -228,13 +238,21 @@ public class SegmentNodeStore implements NodeStore, Observable { SegmentNodeState state = reader.readHeadState(revisions); if (!state.getRecordId().equals(head.get().getRecordId())) { head.set(state); - changeDispatcher.contentChanged(state.getChildNode(ROOT), null); + if (changeDispatcher != null) { + changeDispatcher.contentChanged(state.getChildNode(ROOT), null); + } } } @Override public Closeable addObserver(Observer observer) { - return changeDispatcher.addObserver(observer); + return (changeDispatcher != null) ? + changeDispatcher.addObserver(observer) : + new Closeable() { + @Override + public void close() throws IOException { + } + }; } @Override @Nonnull @@ -509,7 +527,9 @@ public class SegmentNodeStore implements NodeStore, Observable { refreshHead(); if (revisions.setHead(before.getRecordId(), after.getRecordId())) { head.set(after); - changeDispatcher.contentChanged(after.getChildNode(ROOT), info); + if (changeDispatcher != null) { + changeDispatcher.contentChanged(after.getChildNode(ROOT), info); + } refreshHead(); return true; } else { diff --git oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java index 78ee106..ac0e0bc 100644 --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java @@ -336,11 +336,8 @@ public class SegmentNodeStoreService extends ProxyNodeStore private synchronized void registerNodeStore() throws IOException { if (registerSegmentStore()) { - if (toBoolean(property(STANDBY), false)) { - return; - } - - if (registerSegmentNodeStore()) { + boolean standby = toBoolean(property(STANDBY), false); + if (! standby) { Dictionary props = new Hashtable(); props.put(Constants.SERVICE_PID, SegmentNodeStore.class.getName()); props.put("oak.nodestore.description", new String[]{"nodeStoreType=segment"}); @@ -483,34 +480,19 @@ public class SegmentNodeStoreService extends ProxyNodeStore "FileStore statistics" )); - // Register a factory service to expose the FileStore - - providerRegistration = context.getBundleContext().registerService(SegmentStoreProvider.class.getName(), this, null); - - return true; - } - - private SegmentGCOptions newGCOptions() { - boolean pauseCompaction = toBoolean(property(PAUSE_COMPACTION), PAUSE_DEFAULT); - int retryCount = toInteger(property(COMPACTION_RETRY_COUNT), RETRY_COUNT_DEFAULT); - int forceTimeout = toInteger(property(COMPACTION_FORCE_TIMEOUT), FORCE_TIMEOUT_DEFAULT); - - byte gainThreshold = getGainThreshold(); - long sizeDeltaEstimation = toLong(property(COMPACTION_SIZE_DELTA_ESTIMATION), SIZE_DELTA_ESTIMATION_DEFAULT); - - return new SegmentGCOptions(pauseCompaction, gainThreshold, retryCount, forceTimeout) - .setGcSizeDeltaEstimation(sizeDeltaEstimation); - } + // register segment node store - private boolean registerSegmentNodeStore() throws IOException { Dictionary properties = context.getProperties(); name = String.valueOf(properties.get(NAME)); final long blobGcMaxAgeInSecs = toLong(property(PROP_BLOB_GC_MAX_AGE), DEFAULT_BLOB_GC_MAX_AGE); - OsgiWhiteboard whiteboard = new OsgiWhiteboard(context.getBundleContext()); - - segmentNodeStore = SegmentNodeStoreBuilders.builder(store).build(); + SegmentNodeStore.SegmentNodeStoreBuilder segmentNodeStoreBuilder = + SegmentNodeStoreBuilders.builder(store); + if (toBoolean(property(STANDBY), false)) { + segmentNodeStoreBuilder.dispatchChanges(false); + } + segmentNodeStore = segmentNodeStoreBuilder.build(); observerTracker = new ObserverTracker(segmentNodeStore); observerTracker.start(context.getBundleContext()); @@ -550,7 +532,7 @@ public class SegmentNodeStoreService extends ProxyNodeStore if (blobStore instanceof BlobTrackingStore) { final long trackSnapshotInterval = toLong(property(PROP_BLOB_SNAPSHOT_INTERVAL), - DEFAULT_BLOB_SNAPSHOT_INTERVAL); + DEFAULT_BLOB_SNAPSHOT_INTERVAL); String root = property(DIRECTORY); if (Strings.isNullOrEmpty(root)) { root = "repository"; @@ -561,8 +543,8 @@ public class SegmentNodeStoreService extends ProxyNodeStore trackingStore.getTracker().close(); } ((BlobTrackingStore) blobStore).addTracker( - new BlobIdTracker(root, repoId, trackSnapshotInterval, (SharedDataStore) - blobStore)); + new BlobIdTracker(root, repoId, trackSnapshotInterval, (SharedDataStore) + blobStore)); } } @@ -585,9 +567,26 @@ public class SegmentNodeStoreService extends ProxyNodeStore } log.info("SegmentNodeStore initialized"); + + // Register a factory service to expose the FileStore + + providerRegistration = context.getBundleContext().registerService(SegmentStoreProvider.class.getName(), this, null); + return true; } + private SegmentGCOptions newGCOptions() { + boolean pauseCompaction = toBoolean(property(PAUSE_COMPACTION), PAUSE_DEFAULT); + int retryCount = toInteger(property(COMPACTION_RETRY_COUNT), RETRY_COUNT_DEFAULT); + int forceTimeout = toInteger(property(COMPACTION_FORCE_TIMEOUT), FORCE_TIMEOUT_DEFAULT); + + byte gainThreshold = getGainThreshold(); + long sizeDeltaEstimation = toLong(property(COMPACTION_SIZE_DELTA_ESTIMATION), SIZE_DELTA_ESTIMATION_DEFAULT); + + return new SegmentGCOptions(pauseCompaction, gainThreshold, retryCount, forceTimeout) + .setGcSizeDeltaEstimation(sizeDeltaEstimation); + } + private void unregisterNodeStore() { new CompositeRegistration(registrations).unregister(); if (providerRegistration != null) {