Merge branch 'master' into stable-4.3
* master: Remove repository from cache when it's closed Fix RefDirectory not closing resources Fix repository cache never closing repository Change-Id: I9dc9d017806cba25125f69b53812cc3e062ef975 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
commit
27d06cb8d5
|
@ -173,4 +173,39 @@ public void testUnregister() {
|
||||||
assertEquals(0, RepositoryCache.getRegisteredKeys().size());
|
assertEquals(0, RepositoryCache.getRegisteredKeys().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRepositoryUsageCount() throws Exception {
|
||||||
|
FileKey loc = FileKey.exact(db.getDirectory(), db.getFS());
|
||||||
|
Repository d2 = RepositoryCache.open(loc);
|
||||||
|
assertEquals(1, d2.useCnt.get());
|
||||||
|
RepositoryCache.open(FileKey.exact(loc.getFile(), db.getFS()));
|
||||||
|
assertEquals(2, d2.useCnt.get());
|
||||||
|
d2.close();
|
||||||
|
assertEquals(1, d2.useCnt.get());
|
||||||
|
d2.close();
|
||||||
|
assertEquals(0, d2.useCnt.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRepositoryUsageCountWithRegisteredRepository() {
|
||||||
|
assertEquals(1, ((Repository) db).useCnt.get());
|
||||||
|
RepositoryCache.register(db);
|
||||||
|
assertEquals(1, ((Repository) db).useCnt.get());
|
||||||
|
db.close();
|
||||||
|
assertEquals(0, ((Repository) db).useCnt.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRepositoryUnregisteringWhenClosing() throws Exception {
|
||||||
|
FileKey loc = FileKey.exact(db.getDirectory(), db.getFS());
|
||||||
|
Repository d2 = RepositoryCache.open(loc);
|
||||||
|
assertEquals(1, d2.useCnt.get());
|
||||||
|
assertThat(RepositoryCache.getRegisteredKeys(),
|
||||||
|
hasItem(FileKey.exact(db.getDirectory(), db.getFS())));
|
||||||
|
assertEquals(1, RepositoryCache.getRegisteredKeys().size());
|
||||||
|
|
||||||
|
d2.close();
|
||||||
|
|
||||||
|
assertEquals(0, d2.useCnt.get());
|
||||||
|
assertEquals(0, RepositoryCache.getRegisteredKeys().size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,10 +203,10 @@ public void create() throws IOException {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
// We have no resources to close.
|
clearReferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rescan() {
|
private void clearReferences() {
|
||||||
looseRefs.set(RefList.<LooseRef> emptyList());
|
looseRefs.set(RefList.<LooseRef> emptyList());
|
||||||
packedRefs.set(PackedRefList.NO_PACKED_REFS);
|
packedRefs.set(PackedRefList.NO_PACKED_REFS);
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ void rescan() {
|
||||||
@Override
|
@Override
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
super.refresh();
|
super.refresh();
|
||||||
rescan();
|
clearReferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -110,7 +110,8 @@ public static ListenerList getGlobalListenerList() {
|
||||||
return globalListeners;
|
return globalListeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final AtomicInteger useCnt = new AtomicInteger(1);
|
/** Use counter */
|
||||||
|
final AtomicInteger useCnt = new AtomicInteger(1);
|
||||||
|
|
||||||
/** Metadata directory holding the repository's critical files. */
|
/** Metadata directory holding the repository's critical files. */
|
||||||
private final File gitDir;
|
private final File gitDir;
|
||||||
|
@ -864,6 +865,7 @@ public void incrementOpen() {
|
||||||
public void close() {
|
public void close() {
|
||||||
if (useCnt.decrementAndGet() == 0) {
|
if (useCnt.decrementAndGet() == 0) {
|
||||||
doClose();
|
doClose();
|
||||||
|
RepositoryCache.unregister(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,10 +130,10 @@ public static void register(final Repository db) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a repository from the cache.
|
* Close and remove a repository from the cache.
|
||||||
* <p>
|
* <p>
|
||||||
* Removes a repository from the cache, if it is still registered here,
|
* Removes a repository from the cache, if it is still registered here, and
|
||||||
* permitting it to close.
|
* close it.
|
||||||
*
|
*
|
||||||
* @param db
|
* @param db
|
||||||
* repository to unregister.
|
* repository to unregister.
|
||||||
|
@ -141,15 +141,35 @@ public static void register(final Repository db) {
|
||||||
public static void close(final Repository db) {
|
public static void close(final Repository db) {
|
||||||
if (db.getDirectory() != null) {
|
if (db.getDirectory() != null) {
|
||||||
FileKey key = FileKey.exact(db.getDirectory(), db.getFS());
|
FileKey key = FileKey.exact(db.getDirectory(), db.getFS());
|
||||||
cache.unregisterRepository(key);
|
cache.unregisterAndCloseRepository(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a repository from the cache.
|
* Remove a repository from the cache.
|
||||||
* <p>
|
* <p>
|
||||||
* Removes a repository from the cache, if it is still registered here,
|
* Removes a repository from the cache, if it is still registered here. This
|
||||||
* permitting it to close.
|
* method will not close the repository, only remove it from the cache. See
|
||||||
|
* {@link RepositoryCache#close(Repository)} to remove and close the
|
||||||
|
* repository.
|
||||||
|
*
|
||||||
|
* @param db
|
||||||
|
* repository to unregister.
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
public static void unregister(final Repository db) {
|
||||||
|
if (db.getDirectory() != null) {
|
||||||
|
unregister(FileKey.exact(db.getDirectory(), db.getFS()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a repository from the cache.
|
||||||
|
* <p>
|
||||||
|
* Removes a repository from the cache, if it is still registered here. This
|
||||||
|
* method will not close the repository, only remove it from the cache. See
|
||||||
|
* {@link RepositoryCache#close(Repository)} to remove and close the
|
||||||
|
* repository.
|
||||||
*
|
*
|
||||||
* @param location
|
* @param location
|
||||||
* location of the repository to remove.
|
* location of the repository to remove.
|
||||||
|
@ -196,15 +216,17 @@ private Repository openRepository(final Key location,
|
||||||
db = location.open(mustExist);
|
db = location.open(mustExist);
|
||||||
ref = new SoftReference<Repository>(db);
|
ref = new SoftReference<Repository>(db);
|
||||||
cacheMap.put(location, ref);
|
cacheMap.put(location, ref);
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
}
|
|
||||||
db.incrementOpen();
|
db.incrementOpen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
db.incrementOpen();
|
||||||
|
}
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerRepository(final Key location, final Repository db) {
|
private void registerRepository(final Key location, final Repository db) {
|
||||||
db.incrementOpen();
|
|
||||||
SoftReference<Repository> newRef = new SoftReference<Repository>(db);
|
SoftReference<Repository> newRef = new SoftReference<Repository>(db);
|
||||||
Reference<Repository> oldRef = cacheMap.put(location, newRef);
|
Reference<Repository> oldRef = cacheMap.put(location, newRef);
|
||||||
Repository oldDb = oldRef != null ? oldRef.get() : null;
|
Repository oldDb = oldRef != null ? oldRef.get() : null;
|
||||||
|
@ -212,12 +234,17 @@ private void registerRepository(final Key location, final Repository db) {
|
||||||
oldDb.close();
|
oldDb.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unregisterRepository(final Key location) {
|
private Repository unregisterRepository(final Key location) {
|
||||||
Reference<Repository> oldRef = cacheMap.remove(location);
|
Reference<Repository> oldRef = cacheMap.remove(location);
|
||||||
Repository oldDb = oldRef != null ? oldRef.get() : null;
|
return oldRef != null ? oldRef.get() : null;
|
||||||
if (oldDb != null)
|
}
|
||||||
|
|
||||||
|
private void unregisterAndCloseRepository(final Key location) {
|
||||||
|
Repository oldDb = unregisterRepository(location);
|
||||||
|
if (oldDb != null) {
|
||||||
oldDb.close();
|
oldDb.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Collection<Key> getKeys() {
|
private Collection<Key> getKeys() {
|
||||||
return new ArrayList<Key>(cacheMap.keySet());
|
return new ArrayList<Key>(cacheMap.keySet());
|
||||||
|
|
Loading…
Reference in New Issue