Author: chetanm
Date: Wed Jan 6 14:43:14 2016
New Revision: 1723336
URL: http://svn.apache.org/viewvc?rev=1723336&view=rev
Log:
OAK-3819 - Collect and expose statistics related to Segment FileStore operations
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreMonitor.java
(with props)
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStats.java
(with props)
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStatsMBean.java
(with props)
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStatsTest.java
(with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreService.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarWriter.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/package-info.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/package-info.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreServiceTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreService.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreService.java?rev=1723336&r1=1723335&r2=1723336&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreService.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreService.java
Wed Jan 6 14:43:14 2016
@@ -72,6 +72,7 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.segment.file.FileStore;
import org.apache.jackrabbit.oak.plugins.segment.file.FileStore.Builder;
import org.apache.jackrabbit.oak.plugins.segment.file.FileStoreGCMonitor;
+import org.apache.jackrabbit.oak.plugins.segment.file.FileStoreStatsMBean;
import org.apache.jackrabbit.oak.plugins.segment.file.GCMonitorMBean;
import org.apache.jackrabbit.oak.spi.blob.BlobStore;
import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore;
@@ -87,6 +88,7 @@ import org.apache.jackrabbit.oak.spi.whi
import org.apache.jackrabbit.oak.spi.whiteboard.Registration;
import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardExecutor;
import org.apache.jackrabbit.oak.stats.Clock;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
@@ -254,6 +256,9 @@ public class SegmentNodeStoreService ext
policy = ReferencePolicy.DYNAMIC, target = ONLY_STANDALONE_TARGET)
private volatile BlobStore blobStore;
+ @Reference
+ private StatisticsProvider statisticsProvider = StatisticsProvider.NOOP;
+
private ServiceRegistration storeRegistration;
private ServiceRegistration providerRegistration;
private Registration checkpointRegistration;
@@ -263,6 +268,7 @@ public class SegmentNodeStoreService ext
private Registration segmentCacheMBean;
private Registration stringCacheMBean;
private Registration fsgcMonitorMBean;
+ private Registration fileStoreStatsMBean;
private WhiteboardExecutor executor;
private boolean customBlobStore;
@@ -384,7 +390,8 @@ public class SegmentNodeStoreService ext
.withCacheSize(Integer.parseInt(cache))
.withMaxFileSize(Integer.parseInt(size))
.withMemoryMapping("64".equals(mode))
- .withGCMonitor(gcMonitor);
+ .withGCMonitor(gcMonitor)
+ .withStatisticsProvider(statisticsProvider);
if (customBlobStore) {
log.info("Initializing SegmentNodeStore with BlobStore [{}]",
blobStore);
store = storeBuilder.withBlobStore(blobStore).create();
@@ -467,6 +474,12 @@ public class SegmentNodeStoreService ext
CompactionStrategyMBean.TYPE,
"Segment node store compaction strategy settings");
+ fileStoreStatsMBean = registerMBean(whiteboard,
+ FileStoreStatsMBean.class,
+ store.getStats(),
+ FileStoreStatsMBean.TYPE,
+ "FileStore statistics");
+
log.info("SegmentNodeStore initialized");
return true;
}
@@ -542,6 +555,10 @@ public class SegmentNodeStoreService ext
fsgcMonitorMBean.unregister();
fsgcMonitorMBean = null;
}
+ if (fileStoreStatsMBean != null) {
+ fileStoreStatsMBean.unregister();
+ fileStoreStatsMBean = null;
+ }
if (executor != null) {
executor.stop();
executor = null;
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java?rev=1723336&r1=1723335&r2=1723336&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
Wed Jan 6 14:43:14 2016
@@ -82,6 +82,7 @@ import org.apache.jackrabbit.oak.spi.blo
import org.apache.jackrabbit.oak.spi.gc.GCMonitor;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -209,6 +210,8 @@ public class FileStore implements Segmen
private final ReadWriteLock fileStoreLock = new ReentrantReadWriteLock();
+ private final FileStoreStats stats;
+
/**
* Create a new instance of a {@link Builder} for a file store.
* @param directory directory where the tar files are stored
@@ -230,6 +233,7 @@ public class FileStore implements Segmen
private int cacheSize; // 0 -> DEFAULT_MEMORY_CACHE_SIZE
private boolean memoryMapping;
private final LoggingGCMonitor gcMonitor = new LoggingGCMonitor();
+ private StatisticsProvider statsProvider = StatisticsProvider.NOOP;
private Builder(File directory) {
this.directory = directory;
@@ -312,6 +316,19 @@ public class FileStore implements Segmen
}
/**
+ * {@link StatisticsProvider} for collecting statistics related to
FileStore
+ * @param statisticsProvider
+ * @return this instance
+ */
+ @Nonnull
+ public Builder withStatisticsProvider(@Nonnull StatisticsProvider
statisticsProvider) {
+ this.statsProvider = checkNotNull(statisticsProvider);
+ return this;
+ }
+
+ /**
+
+ /**
* Create a new {@link FileStore} instance with the settings specified
in this
* builder. If none of the {@code with} methods have been called
before calling
* this method, a file store with the following default settings is
returned:
@@ -322,6 +339,7 @@ public class FileStore implements Segmen
* <li>cache size: 256MB</li>
* <li>memory mapping: on for 64 bit JVMs off otherwise</li>
* <li>whiteboard: none. No {@link GCMonitor} tracking</li>
+ * <li>statsProvider: StatisticsProvider.NOOP</li>
* </ul>
*
* @return a new file store instance
@@ -330,14 +348,15 @@ public class FileStore implements Segmen
@Nonnull
public FileStore create() throws IOException {
return new FileStore(
- blobStore, directory, root, maxFileSize, cacheSize,
memoryMapping, gcMonitor, false);
+ blobStore, directory, root, maxFileSize, cacheSize,
memoryMapping, gcMonitor, statsProvider, false);
}
}
@Deprecated
public FileStore(BlobStore blobStore, File directory, int maxFileSizeMB,
boolean memoryMapping)
throws IOException {
- this(blobStore, directory, EMPTY_NODE, maxFileSizeMB, 0,
memoryMapping, GCMonitor.EMPTY, false);
+ this(blobStore, directory, EMPTY_NODE, maxFileSizeMB, 0, memoryMapping,
+ GCMonitor.EMPTY, StatisticsProvider.NOOP, false);
}
@Deprecated
@@ -355,24 +374,28 @@ public class FileStore implements Segmen
@Deprecated
public FileStore(File directory, int maxFileSizeMB, int cacheSizeMB,
boolean memoryMapping) throws IOException {
- this(null, directory, EMPTY_NODE, maxFileSizeMB, cacheSizeMB,
memoryMapping, GCMonitor.EMPTY, false);
+ this(null, directory, EMPTY_NODE, maxFileSizeMB, cacheSizeMB,
memoryMapping,
+ GCMonitor.EMPTY, StatisticsProvider.NOOP, false);
}
@Deprecated
FileStore(File directory, NodeState initial, int maxFileSize) throws
IOException {
- this(null, directory, initial, maxFileSize, -1,
MEMORY_MAPPING_DEFAULT, GCMonitor.EMPTY, false);
+ this(null, directory, initial, maxFileSize, -1, MEMORY_MAPPING_DEFAULT,
+ GCMonitor.EMPTY, StatisticsProvider.NOOP, false);
}
@Deprecated
public FileStore(
BlobStore blobStore, final File directory, NodeState initial, int
maxFileSizeMB,
int cacheSizeMB, boolean memoryMapping) throws IOException {
- this(blobStore, directory, initial, maxFileSizeMB, cacheSizeMB,
memoryMapping, GCMonitor.EMPTY, false);
+ this(blobStore, directory, initial, maxFileSizeMB, cacheSizeMB,
memoryMapping,
+ GCMonitor.EMPTY, StatisticsProvider.NOOP,false);
}
private FileStore(
BlobStore blobStore, final File directory, NodeState initial, int
maxFileSizeMB,
- int cacheSizeMB, boolean memoryMapping, GCMonitor gcMonitor,
boolean readonly)
+ int cacheSizeMB, boolean memoryMapping, GCMonitor gcMonitor,
StatisticsProvider statsProvider,
+ boolean readonly)
throws IOException {
if (readonly) {
@@ -419,6 +442,10 @@ public class FileStore implements Segmen
}
}
+ long initialSize = size();
+ this.approximateSize = new AtomicLong(initialSize);
+ this.stats = new FileStoreStats(statsProvider, this, initialSize);
+
if (!readonly) {
if (indices.length > 0) {
this.writeNumber = indices[indices.length - 1] + 1;
@@ -427,7 +454,7 @@ public class FileStore implements Segmen
}
this.writeFile = new File(directory, String.format(
FILE_NAME_FORMAT, writeNumber, "a"));
- this.writer = new TarWriter(writeFile);
+ this.writer = new TarWriter(writeFile, stats);
}
RecordId id = null;
@@ -512,13 +539,10 @@ public class FileStore implements Segmen
}
});
-
- approximateSize = new AtomicLong(size());
} else {
flushThread = null;
compactionThread = null;
diskSpaceThread = null;
- approximateSize = null;
}
sufficientDiskSpace = new AtomicBoolean(true);
@@ -691,7 +715,7 @@ public class FileStore implements Segmen
public long size() {
fileStoreLock.readLock().lock();
try {
- long size = writeFile.length();
+ long size = writeFile != null ? writeFile.length() : 0;
for (TarReader reader : readers) {
size += reader.size();
}
@@ -701,6 +725,15 @@ public class FileStore implements Segmen
}
}
+ public int readerCount(){
+ fileStoreLock.readLock().lock();
+ try {
+ return readers.size();
+ } finally {
+ fileStoreLock.readLock().unlock();
+ }
+ }
+
/**
* Returns the number of segments in this TarMK instance.
*
@@ -744,6 +777,10 @@ public class FileStore implements Segmen
return estimate;
}
+ public FileStoreStats getStats() {
+ return stats;
+ }
+
public void flush() throws IOException {
synchronized (persistedHead) {
RecordId before = persistedHead.get();
@@ -883,6 +920,7 @@ public class FileStore implements Segmen
cm.remove(cleanedIds);
long finalSize = size();
approximateSize.set(finalSize);
+ stats.reclaimed(initialSize - finalSize);
gcMonitor.cleaned(initialSize - finalSize, finalSize);
gcMonitor.info("TarMK GC #{}: cleanup completed in {} ({} ms). Post
cleanup size is {} ({} bytes)" +
" and space reclaimed {} ({} bytes). Compaction map
weight/depth is {}/{} ({} bytes/{}).",
@@ -1255,7 +1293,7 @@ public class FileStore implements Segmen
writeFile = new File(
directory,
String.format(FILE_NAME_FORMAT, writeNumber, "a"));
- writer = new TarWriter(writeFile);
+ writer = new TarWriter(writeFile, stats);
}
}
@@ -1352,13 +1390,13 @@ public class FileStore implements Segmen
public ReadOnlyStore(File directory) throws IOException {
super(null, directory, EMPTY_NODE, -1, 0, MEMORY_MAPPING_DEFAULT,
- GCMonitor.EMPTY, true);
+ GCMonitor.EMPTY, StatisticsProvider.NOOP, true);
}
public ReadOnlyStore(File directory, BlobStore blobStore)
throws IOException {
super(blobStore, directory, EMPTY_NODE, -1, 0,
- MEMORY_MAPPING_DEFAULT, GCMonitor.EMPTY, true);
+ MEMORY_MAPPING_DEFAULT, GCMonitor.EMPTY,
StatisticsProvider.NOOP, true);
}
/**
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreMonitor.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreMonitor.java?rev=1723336&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreMonitor.java
(added)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreMonitor.java
Wed Jan 6 14:43:14 2016
@@ -0,0 +1,52 @@
+/*
+ * 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.segment.file;
+
+/**
+ * FileStoreMonitor are notified for any writes or deletes
+ * performed by FileStore
+ */
+interface FileStoreMonitor {
+ FileStoreMonitor DEFAULT = new FileStoreMonitor() {
+ @Override
+ public void written(long bytes) {
+
+ }
+
+ @Override
+ public void reclaimed(long bytes) {
+
+ }
+ };
+
+ /**
+ * Notifies the monitor when data is written
+ *
+ * @param bytes number of bytes written
+ */
+ void written(long bytes);
+
+ /**
+ * Notifies the monitor when memory is reclaimed
+ *
+ * @param bytes number of bytes reclaimed
+ */
+ void reclaimed(long bytes);
+}
Propchange:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreMonitor.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStats.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStats.java?rev=1723336&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStats.java
(added)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStats.java
Wed Jan 6 14:43:14 2016
@@ -0,0 +1,98 @@
+/*
+ * 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.segment.file;
+
+import javax.annotation.Nonnull;
+import javax.management.openmbean.CompositeData;
+
+import org.apache.jackrabbit.api.stats.TimeSeries;
+import org.apache.jackrabbit.oak.commons.IOUtils;
+import org.apache.jackrabbit.oak.stats.CounterStats;
+import org.apache.jackrabbit.oak.stats.MeterStats;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.apache.jackrabbit.oak.stats.StatsOptions;
+
+import static org.apache.jackrabbit.stats.TimeSeriesStatsUtil.asCompositeData;
+
+public class FileStoreStats implements FileStoreStatsMBean, FileStoreMonitor {
+ public static final String SEGMENT_REPO_SIZE = "SEGMENT_REPO_SIZE";
+ public static final String SEGMENT_WRITES = "SEGMENT_WRITES";
+ private final StatisticsProvider statisticsProvider;
+ private final FileStore store;
+ private final MeterStats writeStats;
+ private final CounterStats repoSize;
+
+ public FileStoreStats(StatisticsProvider statisticsProvider, FileStore
store, long initialSize) {
+ this.statisticsProvider = statisticsProvider;
+ this.store = store;
+ this.writeStats = statisticsProvider.getMeter(SEGMENT_WRITES,
StatsOptions.DEFAULT);
+ this.repoSize = statisticsProvider.getCounterStats(SEGMENT_REPO_SIZE,
StatsOptions.DEFAULT);
+ repoSize.inc(initialSize);
+ }
+
+ //~-----------------------------< FileStoreMonitor >
+
+ @Override
+ public void written(long delta) {
+ writeStats.mark(delta);
+ repoSize.inc(delta);
+ }
+
+ @Override
+ public void reclaimed(long size) {
+ repoSize.dec(size);
+ }
+
+ //~--------------------------------< FileStoreStatsMBean >
+
+ @Override
+ public long getApproximateSize() {
+ return repoSize.getCount();
+ }
+
+ @Override
+ public int getTarFileCount() {
+ return store.readerCount() + 1; //1 for the writer
+ }
+
+ @Nonnull
+ @Override
+ public CompositeData getWriteStats() {
+ return asCompositeData(getTimeSeries(SEGMENT_WRITES), SEGMENT_WRITES);
+ }
+
+ @Nonnull
+ @Override
+ public CompositeData getRepositorySize() {
+ return asCompositeData(getTimeSeries(SEGMENT_REPO_SIZE),
SEGMENT_REPO_SIZE);
+ }
+
+ @Override
+ public String fileStoreInfoAsString() {
+ return String.format("Segment store size : %s%n" +
+ "Number of tar files : %d",
+ IOUtils.humanReadableByteCount(getApproximateSize()),
+ getTarFileCount());
+ }
+
+ private TimeSeries getTimeSeries(String name) {
+ return statisticsProvider.getStats().getTimeSeries(name, true);
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStats.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStatsMBean.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStatsMBean.java?rev=1723336&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStatsMBean.java
(added)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStatsMBean.java
Wed Jan 6 14:43:14 2016
@@ -0,0 +1,43 @@
+/*
+ * 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.segment.file;
+
+import javax.management.openmbean.CompositeData;
+
+public interface FileStoreStatsMBean {
+
+ String TYPE = "FileStoreStats";
+
+ long getApproximateSize();
+
+ int getTarFileCount();
+
+ /**
+ * @return time series of the writes to repository
+ */
+ CompositeData getWriteStats();
+
+ /**
+ * @return time series of the writes to repository
+ */
+ CompositeData getRepositorySize();
+
+ String fileStoreInfoAsString();
+}
Propchange:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStatsMBean.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarWriter.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarWriter.java?rev=1723336&r1=1723335&r2=1723336&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarWriter.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarWriter.java
Wed Jan 6 14:43:14 2016
@@ -116,6 +116,8 @@ class TarWriter implements Closeable {
*/
private final File file;
+ private final FileStoreMonitor monitor;
+
/**
* File handle. Initialized lazily in
* {@link #writeEntry(long, long, byte[], int, int)} to avoid creating
@@ -151,7 +153,12 @@ class TarWriter implements Closeable {
private final SortedMap<UUID, List<UUID>> graph = newTreeMap();
TarWriter(File file) {
+ this(file, FileStoreMonitor.DEFAULT);
+ }
+
+ TarWriter(File file, FileStoreMonitor monitor) {
this.file = file;
+ this.monitor = monitor;
}
/**
@@ -223,6 +230,7 @@ class TarWriter implements Closeable {
channel = access.getChannel();
}
+ long initialLength = access.getFilePointer();
access.write(header);
access.write(data, offset, size);
int padding = getPaddingSize(size);
@@ -230,11 +238,11 @@ class TarWriter implements Closeable {
access.write(ZERO_BYTES, 0, padding);
}
- long length = access.getFilePointer();
- checkState(length <= Integer.MAX_VALUE);
+ long currentLength = access.getFilePointer();
+ checkState(currentLength <= Integer.MAX_VALUE);
TarEntry entry = new TarEntry(
uuid.getMostSignificantBits(), uuid.getLeastSignificantBits(),
- (int) (length - size - padding), size);
+ (int) (currentLength - size - padding), size);
index.put(uuid, entry);
if (isDataSegmentId(uuid.getLeastSignificantBits())) {
@@ -258,7 +266,8 @@ class TarWriter implements Closeable {
}
}
- return length;
+ monitor.written(currentLength - initialLength);
+ return currentLength;
}
/**
@@ -314,13 +323,19 @@ class TarWriter implements Closeable {
// trailing two zero blocks. This code is synchronized on the file
// instance to ensure that no concurrent thread is still flushing
// the file when we close the file handle.
+ long initialPosition, currentPosition;
synchronized (file) {
+ initialPosition = access.getFilePointer();
writeGraph();
writeIndex();
access.write(ZERO_BYTES);
access.write(ZERO_BYTES);
+
+ currentPosition = access.getFilePointer();
access.close();
}
+
+ monitor.written(currentPosition - initialPosition);
}
private void writeGraph() throws IOException {
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/package-info.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/package-info.java?rev=1723336&r1=1723335&r2=1723336&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/package-info.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/package-info.java
Wed Jan 6 14:43:14 2016
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("4.0.0")
+@Version("4.1.0")
@Export(optional = "provide:=true")
package org.apache.jackrabbit.oak.plugins.segment.file;
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/package-info.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/package-info.java?rev=1723336&r1=1723335&r2=1723336&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/package-info.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/package-info.java
Wed Jan 6 14:43:14 2016
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("8.0.0")
+@Version("8.1.0")
@Export(optional = "provide:=true")
package org.apache.jackrabbit.oak.plugins.segment;
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreServiceTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreServiceTest.java?rev=1723336&r1=1723335&r2=1723336&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreServiceTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreServiceTest.java
Wed Jan 6 14:43:14 2016
@@ -29,7 +29,9 @@ import java.util.Map;
import org.apache.jackrabbit.oak.spi.blob.BlobStore;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -43,6 +45,11 @@ public class SegmentNodeStoreServiceTest
@Rule
public TemporaryFolder folder = new TemporaryFolder();
+ @Before
+ public void setUp(){
+ context.registerService(StatisticsProvider.class,
StatisticsProvider.NOOP);
+ }
+
/**
* A NodeStore service should be registered when a BlobStore service is not
* available and the "customBlobStore" configuration property is false.
Added:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStatsTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStatsTest.java?rev=1723336&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStatsTest.java
(added)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStatsTest.java
Wed Jan 6 14:43:14 2016
@@ -0,0 +1,92 @@
+/*
+ * 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.segment.file;
+
+import java.io.File;
+import java.util.UUID;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.apache.jackrabbit.oak.commons.concurrent.ExecutorCloser;
+import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+import org.apache.jackrabbit.oak.stats.DefaultStatisticsProvider;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import static com.google.common.base.Charsets.UTF_8;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+public class FileStoreStatsTest {
+ @Rule
+ public final TemporaryFolder segmentFolder = new TemporaryFolder();
+
+ private FileStore fileStore;
+ private ScheduledExecutorService executor =
Executors.newSingleThreadScheduledExecutor();
+ private StatisticsProvider statsProvider = new
DefaultStatisticsProvider(executor);
+
+ @Before
+ public void createFileStore() throws Exception {
+ BlobStore blobStore = mock(BlobStore.class);
+ fileStore = FileStore.newFileStore(segmentFolder.newFolder())
+ .withBlobStore(blobStore)
+ .withStatisticsProvider(statsProvider).create();
+ }
+
+ @After
+ public void shutDown(){
+ new ExecutorCloser(executor).close();
+ }
+
+ @Test
+ public void initCall() throws Exception{
+ FileStoreStats stats = new FileStoreStats(statsProvider, fileStore,
1000);
+ assertEquals(1000, stats.getApproximateSize());
+
+ stats.written(500);
+ assertEquals(1500, stats.getApproximateSize());
+
+ stats.reclaimed(250);
+ assertEquals(1250, stats.getApproximateSize());
+
+ assertEquals(1, stats.getTarFileCount());
+ }
+
+ @Test
+ public void tarWriterIntegration() throws Exception{
+ FileStoreStats stats = new FileStoreStats(statsProvider, fileStore, 0);
+ UUID id = UUID.randomUUID();
+ long msb = id.getMostSignificantBits();
+ long lsb = id.getLeastSignificantBits() & (-1 >>> 4); // OAK-1672
+ byte[] data = "Hello, World!".getBytes(UTF_8);
+
+ File file = segmentFolder.newFile();
+ TarWriter writer = new TarWriter(file, stats);
+ writer.writeEntry(msb, lsb, data, 0, data.length);
+ writer.close();
+
+ assertEquals(stats.getApproximateSize(), file.length());
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStoreStatsTest.java
------------------------------------------------------------------------------
svn:eol-style = native