aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Borowitz <dborowitz@google.com>2016-07-14 12:11:51 -0400
committerDave Borowitz <dborowitz@google.com>2016-07-18 15:57:41 -0400
commit0f1c361e62db3e685cc9b81733fe2cfd794a9e99 (patch)
tree185c138487fb1bedad35da777ea6df736d658f9f
parent18e9db306b52d2b49c78d0558d51f4a04cca1764 (diff)
downloadjgit-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.java55
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java2
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());
}