summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2020-01-03 18:16:42 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2020-01-28 11:24:06 +0100
commit1f9c717ff709e26d44090bc1b71be7c4c2b2a0fd (patch)
tree90270201ed927f924bab635ff52b46b325e97fad
parent187b7ad72e97adb3b20aea3b44c3f23c451ea190 (diff)
downloadjgit-1f9c717ff709e26d44090bc1b71be7c4c2b2a0fd.tar.gz
jgit-1f9c717ff709e26d44090bc1b71be7c4c2b2a0fd.zip
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>
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java53
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheStats.java9
2 files changed, 52 insertions, 10 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java
index e8ab73538b..3b4f662b90 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java
+++ b/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.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
+import java.util.Collections;
+import java.util.Map;
import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.atomic.LongAdder;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.internal.JGitText;
@@ -184,18 +188,21 @@ public class WindowCache {
/**
* Record files opened by cache
*
- * @param count
+ * @param delta
* delta of number of files opened by cache
*/
- void recordOpenFiles(int count);
+ void recordOpenFiles(int delta);
/**
* Record cached bytes
*
- * @param count
+ * @param pack
+ * pack file the bytes are read from
+ *
+ * @param delta
* 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
@@ -217,6 +224,7 @@ public class WindowCache {
private final LongAdder evictionCount;
private final LongAdder openFileCount;
private final LongAdder openByteCount;
+ private final Map<String, LongAdder> openByteCountPerRepository;
/**
* Constructs an instance with all counts initialized to zero.
@@ -230,6 +238,7 @@ public class WindowCache {
evictionCount = new LongAdder();
openFileCount = new LongAdder();
openByteCount = new LongAdder();
+ openByteCountPerRepository = new ConcurrentHashMap<>();
}
@Override
@@ -260,13 +269,28 @@ public class WindowCache {
}
@Override
- public void recordOpenFiles(int count) {
- openFileCount.add(count);
+ public void recordOpenFiles(int delta) {
+ openFileCount.add(delta);
}
@Override
- public void recordOpenBytes(int count) {
- openByteCount.add(count);
+ public void recordOpenBytes(PackFile pack, int delta) {
+ 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
@@ -323,6 +347,15 @@ public class WindowCache {
totalLoadTime.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) {
@@ -519,12 +552,12 @@ public class WindowCache {
final PageRef<ByteWindow> ref = useStrongRefs
? new StrongRef(p, o, v, queue)
: new SoftRef(p, o, v, (SoftCleanupQueue) queue);
- statsRecorder.recordOpenBytes(ref.getSize());
+ statsRecorder.recordOpenBytes(ref.getPack(), ref.getSize());
return ref;
}
private void clear(PageRef<ByteWindow> ref) {
- statsRecorder.recordOpenBytes(-ref.getSize());
+ statsRecorder.recordOpenBytes(ref.getPack(), -ref.getSize());
statsRecorder.recordEvictions(1);
close(ref.getPack());
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheStats.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheStats.java
index b7f6394df6..65f8dae342 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheStats.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheStats.java
@@ -42,6 +42,8 @@
*/
package org.eclipse.jgit.storage.file;
+import java.util.Map;
+
import javax.management.MXBean;
import org.eclipse.jgit.internal.storage.file.WindowCache;
@@ -226,6 +228,13 @@ public interface WindowCacheStats {
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.
*/
void resetCounters();