Index: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/CachingSegmentReader.java =================================================================== --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/CachingSegmentReader.java (revision 1842211) +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/CachingSegmentReader.java (working copy) @@ -26,6 +26,7 @@ import org.apache.jackrabbit.oak.cache.CacheStats; import org.apache.jackrabbit.oak.spi.blob.BlobStore; import org.apache.jackrabbit.oak.spi.state.NodeState; +import org.apache.jackrabbit.oak.stats.MeterStats; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -55,6 +56,8 @@ @NotNull private final TemplateCache templateCache; + private final MeterStats readStats; + /** * Create a new instance based on the supplied arguments. * @param writer A {@code Supplier} for a the {@code SegmentWriter} used by the segment @@ -66,14 +69,17 @@ * @param templateCacheMB the size of the template cache in MBs or {@code 0} for no cache. */ public CachingSegmentReader( - @NotNull Supplier writer, - @Nullable BlobStore blobStore, - long stringCacheMB, - long templateCacheMB) { + @NotNull Supplier writer, + @Nullable BlobStore blobStore, + long stringCacheMB, + long templateCacheMB, + MeterStats readStats + ) { this.writer = checkNotNull(writer); this.blobStore = blobStore; stringCache = new StringCache(stringCacheMB * 1024 * 1024); templateCache = new TemplateCache(templateCacheMB * 1024 * 1024); + this.readStats = readStats; } /** @@ -121,7 +127,7 @@ @NotNull @Override public SegmentNodeState readNode(@NotNull RecordId id) { - return new SegmentNodeState(this, writer, blobStore, id); + return new SegmentNodeState(this, writer, blobStore, id, readStats); } @NotNull Index: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeBuilder.java =================================================================== --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeBuilder.java (revision 1842211) +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeBuilder.java (working copy) @@ -27,6 +27,7 @@ import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder; import org.apache.jackrabbit.oak.spi.blob.BlobStore; import org.apache.jackrabbit.oak.spi.state.NodeState; +import org.apache.jackrabbit.oak.stats.MeterStats; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -57,6 +58,8 @@ @NotNull private final SegmentWriter writer; + private final MeterStats readStats; + /** * Local update counter for the root builder. * @@ -72,28 +75,34 @@ private long updateCount; SegmentNodeBuilder( - @NotNull SegmentNodeState base, - @Nullable BlobStore blobStore, - @NotNull SegmentReader reader, - @NotNull SegmentWriter writer) { + @NotNull SegmentNodeState base, + @Nullable BlobStore blobStore, + @NotNull SegmentReader reader, + @NotNull SegmentWriter writer, + MeterStats readStats + ) { super(base); this.blobStore = blobStore; this.reader = reader; this.writer = checkNotNull(writer); this.updateCount = 0; + this.readStats = readStats; } private SegmentNodeBuilder( - @NotNull SegmentNodeBuilder parent, - @NotNull String name, - @Nullable BlobStore blobStore, - @NotNull SegmentReader reader, - @NotNull SegmentWriter writer) { + @NotNull SegmentNodeBuilder parent, + @NotNull String name, + @Nullable BlobStore blobStore, + @NotNull SegmentReader reader, + @NotNull SegmentWriter writer, + MeterStats readStats + ) { super(parent, name); this.blobStore = blobStore; this.reader = reader; this.writer = checkNotNull(writer); this.updateCount = -1; + this.readStats = readStats; } /** @@ -128,7 +137,7 @@ public SegmentNodeState getNodeState() { try { NodeState state = super.getNodeState(); - SegmentNodeState sState = new SegmentNodeState(reader, writer, blobStore, writer.writeNode(state)); + SegmentNodeState sState = new SegmentNodeState(reader, writer, blobStore, writer.writeNode(state), readStats); if (state != sState) { set(sState); if(!isChildBuilder()) { @@ -144,7 +153,7 @@ @Override protected MemoryNodeBuilder createChildBuilder(String name) { - return new SegmentNodeBuilder(this, name, blobStore, reader, writer); + return new SegmentNodeBuilder(this, name, blobStore, reader, writer, readStats); } @Override Index: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeState.java =================================================================== --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeState.java (revision 1842211) +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeState.java (working copy) @@ -52,6 +52,8 @@ import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry; import org.apache.jackrabbit.oak.spi.state.NodeState; import org.apache.jackrabbit.oak.spi.state.NodeStateDiff; +import org.apache.jackrabbit.oak.stats.MeterStats; +import org.apache.jackrabbit.oak.stats.NoopStats; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -69,27 +71,43 @@ @NotNull private final Supplier writer; + private final MeterStats readStats; + private volatile RecordId templateId = null; private volatile Template template = null; SegmentNodeState( - @NotNull SegmentReader reader, - @NotNull Supplier writer, - @Nullable BlobStore blobStore, - @NotNull RecordId id) { + @NotNull SegmentReader reader, + @NotNull Supplier writer, + @Nullable BlobStore blobStore, + @NotNull RecordId id, + MeterStats readStats + ) { super(id); this.reader = checkNotNull(reader); this.writer = checkNotNull(memoize(writer)); this.blobStore = blobStore; + this.readStats = readStats; + } + + public SegmentNodeState( + @NotNull SegmentReader reader, + @NotNull SegmentWriter writer, + @Nullable BlobStore blobStore, + @NotNull RecordId id + ) { + this(reader, Suppliers.ofInstance(writer), blobStore, id, NoopStats.INSTANCE); } public SegmentNodeState( - @NotNull SegmentReader reader, - @NotNull SegmentWriter writer, - @Nullable BlobStore blobStore, - @NotNull RecordId id) { - this(reader, Suppliers.ofInstance(writer), blobStore, id); + @NotNull SegmentReader reader, + @NotNull SegmentWriter writer, + @Nullable BlobStore blobStore, + @NotNull RecordId id, + MeterStats readStats + ) { + this(reader, Suppliers.ofInstance(writer), blobStore, id, readStats); } RecordId getTemplateId() { @@ -166,6 +184,7 @@ @Override public long getPropertyCount() { + readStats.mark(); Template template = getTemplate(); long count = template.getPropertyTemplates().length; if (template.getPrimaryType() != null) { @@ -179,6 +198,7 @@ @Override public boolean hasProperty(@NotNull String name) { + readStats.mark(); checkNotNull(name); Template template = getTemplate(); switch (name) { @@ -193,6 +213,7 @@ @Override @Nullable public PropertyState getProperty(@NotNull String name) { + readStats.mark(); checkNotNull(name); Template template = getTemplate(); PropertyState property = null; @@ -229,6 +250,7 @@ @Override @NotNull public Iterable getProperties() { + readStats.mark(); Template template = getTemplate(); PropertyTemplate[] propertyTemplates = template.getPropertyTemplates(); List list = @@ -263,11 +285,13 @@ @Override public boolean getBoolean(@NotNull String name) { + readStats.mark(); return Boolean.TRUE.toString().equals(getValueAsString(name, BOOLEAN)); } @Override public long getLong(String name) { + readStats.mark(); String value = getValueAsString(name, LONG); if (value != null) { return Long.parseLong(value); @@ -278,21 +302,25 @@ @Override @Nullable public String getString(String name) { + readStats.mark(); return getValueAsString(name, STRING); } @Override @NotNull public Iterable getStrings(@NotNull String name) { + readStats.mark(); return getValuesAsStrings(name, STRINGS); } @Override @Nullable public String getName(@NotNull String name) { + readStats.mark(); return getValueAsString(name, NAME); } @Override @NotNull public Iterable getNames(@NotNull String name) { + readStats.mark(); return getValuesAsStrings(name, NAMES); } @@ -392,6 +420,7 @@ @Override public long getChildNodeCount(long max) { + readStats.mark(); String childName = getTemplate().getChildName(); if (childName == Template.ZERO_CHILD_NODES) { return 0; @@ -404,6 +433,7 @@ @Override public boolean hasChildNode(@NotNull String name) { + readStats.mark(); String childName = getTemplate().getChildName(); if (childName == Template.ZERO_CHILD_NODES) { return false; @@ -416,6 +446,7 @@ @Override @NotNull public NodeState getChildNode(@NotNull String name) { + readStats.mark(); String childName = getTemplate().getChildName(); if (childName == Template.MANY_CHILD_NODES) { MapEntry child = getChildNodeMap().getEntry(name); @@ -433,6 +464,7 @@ @Override @NotNull public Iterable getChildNodeNames() { + readStats.mark(); String childName = getTemplate().getChildName(); if (childName == Template.ZERO_CHILD_NODES) { return Collections.emptyList(); @@ -445,6 +477,7 @@ @Override @NotNull public Iterable getChildNodeEntries() { + readStats.mark(); String childName = getTemplate().getChildName(); if (childName == Template.ZERO_CHILD_NODES) { return Collections.emptyList(); @@ -459,11 +492,12 @@ @Override @NotNull public SegmentNodeBuilder builder() { - return new SegmentNodeBuilder(this, blobStore, reader, writer.get()); + return new SegmentNodeBuilder(this, blobStore, reader, writer.get(), readStats); } @Override public boolean compareAgainstBaseState(NodeState base, NodeStateDiff diff) { + readStats.mark(); if (this == base || fastEquals(this, base)) { return true; // no changes } else if (base == EMPTY_NODE || !base.exists()) { // special case Index: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractFileStore.java =================================================================== --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractFileStore.java (revision 1842211) +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractFileStore.java (working copy) @@ -37,13 +37,12 @@ import org.apache.jackrabbit.oak.segment.Segment; import org.apache.jackrabbit.oak.segment.Segment.RecordConsumer; import org.apache.jackrabbit.oak.segment.SegmentBlob; +import org.apache.jackrabbit.oak.segment.SegmentBufferMonitor; import org.apache.jackrabbit.oak.segment.SegmentCache; import org.apache.jackrabbit.oak.segment.SegmentId; import org.apache.jackrabbit.oak.segment.SegmentIdFactory; import org.apache.jackrabbit.oak.segment.SegmentIdProvider; import org.apache.jackrabbit.oak.segment.SegmentNodeState; -import org.apache.jackrabbit.oak.segment.SegmentBufferMonitor; -import org.apache.jackrabbit.oak.segment.spi.persistence.SegmentNodeStorePersistence; import org.apache.jackrabbit.oak.segment.SegmentNotFoundException; import org.apache.jackrabbit.oak.segment.SegmentReader; import org.apache.jackrabbit.oak.segment.SegmentStore; @@ -51,10 +50,12 @@ import org.apache.jackrabbit.oak.segment.SegmentWriter; import org.apache.jackrabbit.oak.segment.file.tar.EntryRecovery; import org.apache.jackrabbit.oak.segment.file.tar.GCGeneration; -import org.apache.jackrabbit.oak.segment.spi.monitor.IOMonitor; import org.apache.jackrabbit.oak.segment.file.tar.TarFiles; import org.apache.jackrabbit.oak.segment.file.tar.TarRecovery; +import org.apache.jackrabbit.oak.segment.spi.monitor.IOMonitor; +import org.apache.jackrabbit.oak.segment.spi.persistence.SegmentNodeStorePersistence; import org.apache.jackrabbit.oak.spi.blob.BlobStore; +import org.apache.jackrabbit.oak.stats.StatsOptions; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -135,7 +136,13 @@ }); this.blobStore = builder.getBlobStore(); this.segmentCache = newSegmentCache(builder.getSegmentCacheSize()); - this.segmentReader = new CachingSegmentReader(this::getWriter, blobStore, builder.getStringCacheSize(), builder.getTemplateCacheSize()); + this.segmentReader = new CachingSegmentReader( + this::getWriter, + blobStore, + builder.getStringCacheSize(), + builder.getTemplateCacheSize(), + builder.getStatsProvider().getMeter("oak.segment.reads", StatsOptions.DEFAULT) + ); this.memoryMapping = builder.getMemoryMapping(); this.ioMonitor = builder.getIOMonitor(); this.segmentBufferMonitor = new SegmentBufferMonitor(builder.getStatsProvider()); Index: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/memory/MemoryStore.java =================================================================== --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/memory/MemoryStore.java (revision 1842211) +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/memory/MemoryStore.java (working copy) @@ -38,6 +38,7 @@ import org.apache.jackrabbit.oak.segment.SegmentTracker; import org.apache.jackrabbit.oak.segment.SegmentWriter; import org.apache.jackrabbit.oak.spi.blob.BlobStore; +import org.apache.jackrabbit.oak.stats.NoopStats; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -69,7 +70,7 @@ } }); this.revisions = new MemoryStoreRevisions(); - this.segmentReader = new CachingSegmentReader(this::getWriter, null, 16, 2); + this.segmentReader = new CachingSegmentReader(this::getWriter, null, 16, 2, NoopStats.INSTANCE); this.segmentWriter = defaultSegmentWriterBuilder("sys").withWriterPool().build(this); revisions.bind(this); segmentWriter.flush();