|
|
@@ -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()); |
|
|
|
} |