Browse Source

WindowCache: add metric for cached bytes per repository

Since ObjectDatabase and PackFile don't know their repository use the
packfile's grand-grand-parent directory as an identifier for the
repository the packfile resides in.

Remove metric for a repository if the number of cached bytes for the
repository drops to 0 in order to ensure the map of cached bytes per
repository doesn't contain repositories which have no data cached in the
WindowCache.

Change-Id: I969ab8029db0a292e7585cbb36ca0baa797da20b
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
stable-5.1
Matthias Sohn 5 years ago
parent
commit
1f9c717ff7
  1. 53
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java
  2. 9
      org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheStats.java

53
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java

@ -47,12 +47,16 @@ package org.eclipse.jgit.internal.storage.file;
import java.io.IOException; import java.io.IOException;
import java.lang.ref.ReferenceQueue; import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.util.Collections;
import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.atomic.LongAdder; import java.util.concurrent.atomic.LongAdder;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.JGitText;
@ -184,18 +188,21 @@ public class WindowCache {
/** /**
* Record files opened by cache * Record files opened by cache
* *
* @param count * @param delta
* delta of number of files opened by cache * delta of number of files opened by cache
*/ */
void recordOpenFiles(int count); void recordOpenFiles(int delta);
/** /**
* Record cached bytes * Record cached bytes
* *
* @param count * @param pack
* pack file the bytes are read from
*
* @param delta
* delta of cached bytes * delta of cached bytes
*/ */
void recordOpenBytes(int count); void recordOpenBytes(PackFile pack, int delta);
/** /**
* Returns a snapshot of this recorder's stats. Note that this may be an * Returns a snapshot of this recorder's stats. Note that this may be an
@ -217,6 +224,7 @@ public class WindowCache {
private final LongAdder evictionCount; private final LongAdder evictionCount;
private final LongAdder openFileCount; private final LongAdder openFileCount;
private final LongAdder openByteCount; private final LongAdder openByteCount;
private final Map<String, LongAdder> openByteCountPerRepository;
/** /**
* Constructs an instance with all counts initialized to zero. * Constructs an instance with all counts initialized to zero.
@ -230,6 +238,7 @@ public class WindowCache {
evictionCount = new LongAdder(); evictionCount = new LongAdder();
openFileCount = new LongAdder(); openFileCount = new LongAdder();
openByteCount = new LongAdder(); openByteCount = new LongAdder();
openByteCountPerRepository = new ConcurrentHashMap<>();
} }
@Override @Override
@ -260,13 +269,28 @@ public class WindowCache {
} }
@Override @Override
public void recordOpenFiles(int count) { public void recordOpenFiles(int delta) {
openFileCount.add(count); openFileCount.add(delta);
} }
@Override @Override
public void recordOpenBytes(int count) { public void recordOpenBytes(PackFile pack, int delta) {
openByteCount.add(count); openByteCount.add(delta);
String repositoryId = repositoryId(pack);
LongAdder la = openByteCountPerRepository
.computeIfAbsent(repositoryId, k -> new LongAdder());
la.add(delta);
if (delta < 0) {
openByteCountPerRepository.computeIfPresent(repositoryId,
(k, v) -> v.longValue() == 0 ? null : v);
}
}
private static String repositoryId(PackFile pack) {
// use repository's gitdir since packfile doesn't know its
// repository
return pack.getPackFile().getParentFile().getParentFile()
.getParent();
} }
@Override @Override
@ -323,6 +347,15 @@ public class WindowCache {
totalLoadTime.reset(); totalLoadTime.reset();
evictionCount.reset(); evictionCount.reset();
} }
@Override
public Map<String, Long> getOpenByteCountPerRepository() {
return Collections.unmodifiableMap(
openByteCountPerRepository.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> Long.valueOf(e.getValue().sum()),
(u, v) -> v)));
}
} }
private static final int bits(int newSize) { private static final int bits(int newSize) {
@ -519,12 +552,12 @@ public class WindowCache {
final PageRef<ByteWindow> ref = useStrongRefs final PageRef<ByteWindow> ref = useStrongRefs
? new StrongRef(p, o, v, queue) ? new StrongRef(p, o, v, queue)
: new SoftRef(p, o, v, (SoftCleanupQueue) queue); : new SoftRef(p, o, v, (SoftCleanupQueue) queue);
statsRecorder.recordOpenBytes(ref.getSize()); statsRecorder.recordOpenBytes(ref.getPack(), ref.getSize());
return ref; return ref;
} }
private void clear(PageRef<ByteWindow> ref) { private void clear(PageRef<ByteWindow> ref) {
statsRecorder.recordOpenBytes(-ref.getSize()); statsRecorder.recordOpenBytes(ref.getPack(), -ref.getSize());
statsRecorder.recordEvictions(1); statsRecorder.recordEvictions(1);
close(ref.getPack()); close(ref.getPack());
} }

9
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheStats.java

@ -42,6 +42,8 @@
*/ */
package org.eclipse.jgit.storage.file; package org.eclipse.jgit.storage.file;
import java.util.Map;
import javax.management.MXBean; import javax.management.MXBean;
import org.eclipse.jgit.internal.storage.file.WindowCache; import org.eclipse.jgit.internal.storage.file.WindowCache;
@ -225,6 +227,13 @@ public interface WindowCacheStats {
*/ */
long getOpenByteCount(); long getOpenByteCount();
/**
* Number of bytes cached per repository
*
* @return number of bytes cached per repository
*/
Map<String, Long> getOpenByteCountPerRepository();
/** /**
* Reset counters. Does not reset open bytes and open files counters. * Reset counters. Does not reset open bytes and open files counters.
*/ */

Loading…
Cancel
Save