|
|
@ -45,8 +45,6 @@ package org.eclipse.jgit.lib; |
|
|
|
|
|
|
|
|
|
|
|
import java.io.File; |
|
|
|
import java.io.File; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.IOException; |
|
|
|
import java.lang.ref.Reference; |
|
|
|
|
|
|
|
import java.lang.ref.SoftReference; |
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.Iterator; |
|
|
|
import java.util.Iterator; |
|
|
@ -202,8 +200,7 @@ public class RepositoryCache { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
FileKey key = new FileKey(gitDir, repo.getFS()); |
|
|
|
FileKey key = new FileKey(gitDir, repo.getFS()); |
|
|
|
Reference<Repository> repoRef = cache.cacheMap.get(key); |
|
|
|
return cache.cacheMap.get(key) == repo; |
|
|
|
return repoRef != null && repoRef.get() == repo; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** Unregister all repositories from the cache. */ |
|
|
|
/** Unregister all repositories from the cache. */ |
|
|
@ -219,7 +216,7 @@ public class RepositoryCache { |
|
|
|
cache.configureEviction(repositoryCacheConfig); |
|
|
|
cache.configureEviction(repositoryCacheConfig); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private final ConcurrentHashMap<Key, Reference<Repository>> cacheMap; |
|
|
|
private final ConcurrentHashMap<Key, Repository> cacheMap; |
|
|
|
|
|
|
|
|
|
|
|
private final Lock[] openLocks; |
|
|
|
private final Lock[] openLocks; |
|
|
|
|
|
|
|
|
|
|
@ -228,7 +225,7 @@ public class RepositoryCache { |
|
|
|
private volatile long expireAfter; |
|
|
|
private volatile long expireAfter; |
|
|
|
|
|
|
|
|
|
|
|
private RepositoryCache() { |
|
|
|
private RepositoryCache() { |
|
|
|
cacheMap = new ConcurrentHashMap<Key, Reference<Repository>>(); |
|
|
|
cacheMap = new ConcurrentHashMap<Key, Repository>(); |
|
|
|
openLocks = new Lock[4]; |
|
|
|
openLocks = new Lock[4]; |
|
|
|
for (int i = 0; i < openLocks.length; i++) { |
|
|
|
for (int i = 0; i < openLocks.length; i++) { |
|
|
|
openLocks[i] = new Lock(); |
|
|
|
openLocks[i] = new Lock(); |
|
|
@ -261,19 +258,15 @@ public class RepositoryCache { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("resource") |
|
|
|
|
|
|
|
private Repository openRepository(final Key location, |
|
|
|
private Repository openRepository(final Key location, |
|
|
|
final boolean mustExist) throws IOException { |
|
|
|
final boolean mustExist) throws IOException { |
|
|
|
Reference<Repository> ref = cacheMap.get(location); |
|
|
|
Repository db = cacheMap.get(location); |
|
|
|
Repository db = ref != null ? ref.get() : null; |
|
|
|
|
|
|
|
if (db == null) { |
|
|
|
if (db == null) { |
|
|
|
synchronized (lockFor(location)) { |
|
|
|
synchronized (lockFor(location)) { |
|
|
|
ref = cacheMap.get(location); |
|
|
|
db = cacheMap.get(location); |
|
|
|
db = ref != null ? ref.get() : null; |
|
|
|
|
|
|
|
if (db == null) { |
|
|
|
if (db == null) { |
|
|
|
db = location.open(mustExist); |
|
|
|
db = location.open(mustExist); |
|
|
|
ref = new SoftReference<Repository>(db); |
|
|
|
cacheMap.put(location, db); |
|
|
|
cacheMap.put(location, ref); |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
db.incrementOpen(); |
|
|
|
db.incrementOpen(); |
|
|
|
} |
|
|
|
} |
|
|
@ -285,16 +278,13 @@ public class RepositoryCache { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void registerRepository(final Key location, final Repository db) { |
|
|
|
private void registerRepository(final Key location, final Repository db) { |
|
|
|
SoftReference<Repository> newRef = new SoftReference<Repository>(db); |
|
|
|
Repository oldDb = cacheMap.put(location, db); |
|
|
|
Reference<Repository> oldRef = cacheMap.put(location, newRef); |
|
|
|
|
|
|
|
Repository oldDb = oldRef != null ? oldRef.get() : null; |
|
|
|
|
|
|
|
if (oldDb != null) |
|
|
|
if (oldDb != null) |
|
|
|
oldDb.close(); |
|
|
|
oldDb.close(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Repository unregisterRepository(final Key location) { |
|
|
|
private Repository unregisterRepository(final Key location) { |
|
|
|
Reference<Repository> oldRef = cacheMap.remove(location); |
|
|
|
return cacheMap.remove(location); |
|
|
|
return oldRef != null ? oldRef.get() : null; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private boolean isExpired(Repository db) { |
|
|
|
private boolean isExpired(Repository db) { |
|
|
@ -316,8 +306,7 @@ public class RepositoryCache { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void clearAllExpired() { |
|
|
|
private void clearAllExpired() { |
|
|
|
for (Reference<Repository> ref : cacheMap.values()) { |
|
|
|
for (Repository db : cacheMap.values()) { |
|
|
|
Repository db = ref.get(); |
|
|
|
|
|
|
|
if (isExpired(db)) { |
|
|
|
if (isExpired(db)) { |
|
|
|
RepositoryCache.close(db); |
|
|
|
RepositoryCache.close(db); |
|
|
|
} |
|
|
|
} |
|
|
@ -325,7 +314,7 @@ public class RepositoryCache { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void clearAll() { |
|
|
|
private void clearAll() { |
|
|
|
for (Iterator<Map.Entry<Key, Reference<Repository>>> i = cacheMap |
|
|
|
for (Iterator<Map.Entry<Key, Repository>> i = cacheMap |
|
|
|
.entrySet().iterator(); i.hasNext();) { |
|
|
|
.entrySet().iterator(); i.hasNext();) { |
|
|
|
unregisterAndCloseRepository(i.next().getKey()); |
|
|
|
unregisterAndCloseRepository(i.next().getKey()); |
|
|
|
} |
|
|
|
} |
|
|
|