diff options
author | Dave Borowitz <dborowitz@google.com> | 2016-07-14 12:11:51 -0400 |
---|---|---|
committer | Dave Borowitz <dborowitz@google.com> | 2016-07-18 15:57:41 -0400 |
commit | 0f1c361e62db3e685cc9b81733fe2cfd794a9e99 (patch) | |
tree | 185c138487fb1bedad35da777ea6df736d658f9f | |
parent | 18e9db306b52d2b49c78d0558d51f4a04cca1764 (diff) | |
download | jgit-0f1c361e62db3e685cc9b81733fe2cfd794a9e99.tar.gz jgit-0f1c361e62db3e685cc9b81733fe2cfd794a9e99.zip |
DfsObjectDatabase: Expose PackList and move markDirty there
What's invalidated when an object database is "dirty" is not the whole
database, but rather a specific list of packs. If there is a race
between getting the pack list and setting the volatile dirty flag
where the packs are rescanned, we don't need to mark the new pack list
as dirty.
This is a fine point that only really applies if the decision of
whether or not to mark dirty actually requires introspecting the pack
list (say, its timestamps). The general operation of "take whatever
is the current pack list and mark it dirty" may still be inherently
racy, but the cost is not so high.
Change-Id: I159e9154bd8b2d348b4e383627a503e85462dcc6
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java | 55 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java | 2 |
2 files changed, 37 insertions, 20 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java index b28519b16a..538e69a177 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java @@ -68,7 +68,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase { } @Override - void markDirty() { + public void markDirty() { // Always dirty. } }; @@ -186,7 +186,16 @@ public abstract class DfsObjDatabase extends ObjectDatabase { return getPackList().packs; } - PackList getPackList() throws IOException { + /** + * Scan and list all available pack files in the repository. + * + * @return list of available packs, with some additional metadata. The + * returned array is shared with the implementation and must not be + * modified by the caller. + * @throws IOException + * the pack list cannot be initialized. + */ + public PackList getPackList() throws IOException { return scanPacks(NO_PACKS); } @@ -202,7 +211,18 @@ public abstract class DfsObjDatabase extends ObjectDatabase { * implementation and must not be modified by the caller. */ public DfsPackFile[] getCurrentPacks() { - return packList.get().packs; + return getCurrentPackList().packs; + } + + /** + * List currently known pack files in the repository, without scanning. + * + * @return list of available packs, with some additional metadata. The + * returned array is shared with the implementation and must not be + * modified by the caller. + */ + public PackList getCurrentPackList() { + return packList.get(); } /** @@ -460,17 +480,6 @@ public abstract class DfsObjDatabase extends ObjectDatabase { packList.set(NO_PACKS); } - /** - * Mark object database as dirty. - * <p> - * Used when the caller knows that new data might have been written to the - * repository that could invalidate open readers, for example if refs are - * newly scanned. - */ - protected void markDirty() { - packList.get().markDirty(); - } - @Override public void close() { // PackList packs = packList.get(); @@ -481,17 +490,25 @@ public abstract class DfsObjDatabase extends ObjectDatabase { // p.close(); } - static abstract class PackList { + /** Snapshot of packs scanned in a single pass. */ + public static abstract class PackList { /** All known packs, sorted. */ - final DfsPackFile[] packs; + public final DfsPackFile[] packs; - PackList(final DfsPackFile[] packs) { + PackList(DfsPackFile[] packs) { this.packs = packs; } abstract boolean dirty(); - abstract void markDirty(); + /** + * Mark pack list as dirty. + * <p> + * Used when the caller knows that new data might have been written to the + * repository that could invalidate open readers depending on this pack list, + * for example if refs are newly scanned. + */ + public abstract void markDirty(); } private static final class PackListImpl extends PackList { @@ -507,7 +524,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase { } @Override - void markDirty() { + public void markDirty() { dirty = true; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java index 5765399f6d..2e1c90d3ce 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java @@ -310,7 +310,7 @@ public class InMemoryRepository extends DfsRepository { } ids.sort(); sym.sort(); - objdb.markDirty(); + objdb.getCurrentPackList().markDirty(); return new RefCache(ids.toRefList(), sym.toRefList()); } |